I'm writing an assembly program for an assignment where I need to take an array, let's say
array: DB 1, 2, 3, 4, 5
and I need to loop through it and print a star corresponding to the number in the array. So in the example above the program should output:
* * * * *
* * * *
* * *
* *
*
My problem is I'm getting Segmentation faults somewhere in the code and I can't pinpoint where. Anyone have any idea where this is happening?
code:
%INCLUDE "csci224.inc"
SEGMENT .data
array: DB 1, 2, 3, 4, 5, 4, 3, 2, 1
star: DB "*",0,10
n: DB 0
SEGMENT .text
main:
mov edx, 9 ;length of array
mov ecx, 0 ;loop counter
jmp outerloop ;begin outerloop
outerloop:
mov ah, [array+ecx] ;move (array element + loop counter) to ah
movzx ebx, ah ;zero extend ah to ebx
mov [n], ebx ;copy value of array element to variable
mov eax, ebx
inc ecx
;call WriteInt
dec edx
jnz innerloop ;jump to innerloop
innerloop: ;cycle through '[n]', printing a star each time
mov edi, [n]
mov eax, [star]
call WriteString ;print star
dec edi ;decrement counter
jnz innerloop ;is edi zero? if no, loop again
cmp ecx, byte 0 ;if yes, go back to outerloop
jz outerloop
ret
First off, the ret
you have at the end, is not the correct way to end your program! In Windows, you would use ExitProcess
or call exit
if you are linking to the C library. In Linux, you would use int 80H - sys_exit
or syscall - 60
or exit
if you are linking to the C Library.
When using nested loops, first get your outer loop working first; print out each value in the array. Once you have that working, add your "inner" loop to print the stars.
In the following code, I use esi
and ebx
since those must be saved by the callee so we shouldn't need to worry about saving those values.
extern printf, exit
global main
SEGMENT .data
array: DB 1, 2, 3, 4, 5, 4, 3, 2, 1
array_len equ $ - array
star: DB "*", 0
SEGMENT .text
main:
mov esi, 0 ;loop counter
.ArrayLoop:
;~ Get array value to use as PrintStars loop counter, esi is index into array
movzx ebx, byte [array + esi]
;~ increase ArrayLoop "Outer Loop" counter
inc esi
cmp esi, array_len
;~ if esi > array_len, we are done
jg .Done
.PrintStars:
;~ print stars here
;~ decrease "Inner Loop" counter
dec ebx
;~ If ebx != 0, continue "Inner Loop"
jnz .PrintStars
;~ ebx == 0, print new line char and continue "Outer Loop"
;~ print newline char here
jmp .ArrayLoop
.Done:
call exit
Which would print out the stars as: according to the array in your source.
If you wanted to make a pyramid, read this
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.