我目前正在尝试学习汇编语言。但我被卡住了。 假设我有这个C代码:
__asm__ ("movq $100, %rax;"
".loop:"
//Some code
"decq %rax;"
"cmpq $0, (%rax);"
"jnz .loop;"
);
现在我想用汇编语言做同样的事情。我试过这样的话:
<Page.BottomAppBar>
以seg错误编译并运行结果。如果我删除cmpq行,它不会出错。但当然程序不会终止。
所以基本上我的问题是我在这里做错了什么?
提前致谢。
答案 0 :(得分:8)
以下说明:
cmpq $0, (%rax)
正在访问rax
寄存器指定的内存地址,其值为99
。
第一个内存页面未映射。该内存地址99
属于第一个内存页面。因此,上述访问会导致分段错误。
你不想要间接,而是你想要的:
cmpq $0, %rax
也就是说,您希望与 然而,请考虑优化 rax
的内容进行比较,而不是rax
指定的内存地址中的内容。< / p>
cmp
指令远:decq %rax
紧接在cmp $0, %rax
指令之前,如果ZF
为零,则设置rax
。然后根据ZF
标志的状态执行条件跳转:decq %rax
cmpq $0, %rax
jnz .loop
dec
指令会影响ZF
标记(如cmp
所示),因此如果递减rax
结果为零,则会设置ZF
。您可以利用这一事实,并在jnz
之后直接放置dec
。您根本不需要cmp
:decq %rax
jnz .loop
答案 1 :(得分:7)
cmpq $0, (%rax)
该指令将尝试读取rax
中地址的内存。
rax
将是99。地址99未映射,因此您的程序会出现段错误。
您打算将rax
中的值与0进行比较,因此请删除括号。
cmpq $0, %rax
答案 2 :(得分:3)
从%rax中删除括号以获取rax的值。添加括号基本上告诉汇编程序,&#34;嘿! rax持有一个地址,请返回该地址中的内容&#34;。
因此,
cmpq $0, %rax
是你需要做的。