我目前正在学习英特尔x86程序集,并且在尝试构建一个循环10次的简单循环时遇到了问题。它应该在10个循环之后停止,但它会一直持续下去。
这是我正在使用的代码:
section .data
msg db "Hello, World!", 0x0a
len equ $-msg
section .text
global _start
_start:
mov cx, 10 ; loop counter
_loop_start:
mov ebx, 0x01
mov ecx, msg
mov edx, len
mov eax, 0x04
int 0x80
dec cx
cmp cx, 0
jge _loop_start
_done:
mov ebx, 0x00
mov eax, 0x01
int 0x80
在尝试编写此代码之前,我查看this tutorial进行简单算术。
我这样编译:
nasm -f elf64 test.s -o test.o
并像这样链接:
ld -s -o test_exec test.o
提前致谢, Anickyan
答案 0 :(得分:4)
cx是ecx的低16位部分。您的代码建议您可能认为您的循环将运行10次(在循环之前将cx设置为10)。但是然后用mov ecx, msg
的msg地址覆盖该值。因此,您将从该数字的低16位开始倒数至0。
但是减量甚至没有影响,因为在下一次迭代中你用msg的地址再次覆盖ecx。循环再次开始。这是一个无限循环。
你在调试器中检查了软件吗?这可以帮到很多。
答案 1 :(得分:0)
如果“覆盖”问题得到解决,并且我们开始用计数器10来减少每个电路的计数器,如果我们分支,如果计数器的值大于或等于0,那么我们就变成了一个循环11次。
另外,我们也可以使用zeroflag进行分支(如果没有设置zeroflag):
dec cl
jnz _loop_start
“dec”指令已经涉及标志寄存器,所以如果我们想检查一个值是否减少到零,我们就不需要“cmp” - 指令。
德克