Mac M1平台ARM64汇编CMP指令不符合预期问题求助
ARM64汇编(Mac M1)常见问题解答
问题1:CMP指令看似“失效”,不该执行的代码被执行
核心问题大概率是分支指令搭配错误,或是寄存器值被意外覆盖。
举个典型错误示例:
.text .global _main _main: mov x3, #1 ; x3赋值为1,和#2不相等 cmp x3, #2 b _print_me ; 这里用了无条件跳转B,完全忽略CMP结果 b _exit _print_me: adrp x0, hello@PAGE add x0, x0, hello@PAGEOFF bl _printf _exit: mov x0, #0 mov x16, #1 svc #0x80 .data hello: .asciz "Hello World\n"
上述代码中,b _print_me是无条件分支指令,不管CMP的比较结果如何都会跳转。正确的做法是根据CMP结果使用条件分支:
- 若要在
x3 == 2时执行_print_me,用beq _print_me(相等则跳转) - 若要在
x3 != 2时执行,用bne _print_me(不等则跳转)
另外要检查x3的值是否被其他指令意外修改——比如在CMP之前,是否有调用系统函数、其他赋值指令覆盖了x3?ARM64有固定的调用约定,部分寄存器属于调用者保存,新手容易忽略这一点。
问题2:两个标签的代码被同时执行
这是因为程序执行完第一个标签的代码后,没有主动终止或跳转,CPU会自动顺序执行后续指令。
错误示例:
.text .global _main _main: b _print_first _print_first: adrp x0, str1@PAGE add x0, x0, str1@PAGEOFF bl _printf _print_second: adrp x0, str2@PAGE add x0, x0, str2@PAGEOFF bl _printf _exit: mov x0, #0 mov x16, #1 svc #0x80 .data str1: .asciz "First line\n" str2: .asciz "Second line\n"
执行完_print_first的代码后,CPU会继续往下执行_print_second的指令流。解决方法是在第一个标签执行完毕后,跳转至退出逻辑:
_print_first: adrp x0, str1@PAGE add x0, x0, str1@PAGEOFF bl _printf b _exit ; 执行完后跳转到退出逻辑,避免继续执行后续代码
另外,Mac M1的ARM64汇编要注意系统调用的正确方式:通过mov x16, #1(exit的系统调用号)后触发svc #0x80,确保程序能正确终止,而非让CPU继续执行后续的无效指令。
内容的提问来源于stack exchange,提问作者Lord Diablo
相关产品推荐
相关产品推荐

