我正在编写一个程序集程序,我需要一个数组,比如说
array: DB 1, 2, 3, 4, 5
我需要遍历它并打印一个与数组中的数字对应的星号。所以在上面的例子中,程序应该输出:
* * * * *
* * * *
* * *
* *
*
我的问题是我在代码中的某个地方遇到了分段错误,我无法确定在哪里。任何人都知道这是怎么回事?
代码:
%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
答案 0 :(得分:1)
首先,你最后的ret
不是结束你的程序的正确方法!在Windows中,如果要链接到C库,则可以使用ExitProcess
或调用exit
。在Linux中,如果要链接到C库,则可以使用int 80H - sys_exit
或syscall - 60
或exit
。
使用嵌套循环时,首先让外循环工作;打印出数组中的每个值。完成后,添加“内部”循环以打印星星。
在下面的代码中,我使用esi
和ebx
,因为这些必须由被调用方保存,因此我们不必担心保存这些值。
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
哪会打印出星星: 根据您的来源中的数组。
如果您想制作金字塔,请阅读this