我无法使 cmp 在 Mac M1 上的 arm64 汇编上工作。我已经尝试了一切,但似乎没有任何效果。 例如,在下面的代码中,cmp 应该评估为 false 并且不打印,而是打印 Hello World。为什么?
.global _start
.align 2
_start:
mov x3, #1
cmp x3, #2
b.eq _print_me
_print_me:
adr x1, _helloworld
mov x2, #15
mov x16, #4
svc 0
b _terminate
_helloworld: .ascii "Hello World\n"
_terminate:
mov x0, #0
mov x16, #1
svc 0
我尝试过更改寄存器......同样的想法。我没有解决方案。 我是装配新手。 谢谢你
编辑 2:为什么使用两个标签打印两个而不是一个?
.global _start
.align 2
_start:
mov x3, #1
cmp x3, #1
b.eq _print_me
b _terminate
_print_me:
adr x1, _helloworld
mov x2, #30
mov x16, #4
svc 0
b _terminate
_print_me2:
adr x1, _helloworld2
mov x2, #30
mov x16, #4
svc 0
b _terminate
_terminate:
mov x0, #0
mov x16, #1
svc #0x80
_helloworld: .ascii "Hello World\n"
_helloworld2: .ascii "Hello World2\n"
你的第一个例子已经由@fuz在评论中回答了:当CPU不采取分支时,它继续执行下一条指令。所以那个分支本质上是没用的。
如果您在反汇编程序中查看第二个示例的问题就会变得很清楚。具体来说是目标字符串。我在这里使用radare2:
[0x100003f48]> x 30 @sym._helloworld
- offset - 8C8D 8E8F 9091 9293 9495 9697 9899 9A9B CDEF0123456789AB
0x100003f8c 4865 6c6c 6f20 576f 726c 640a 4865 6c6c Hello World.Hell
0x100003f9c 6f20 576f 726c 6432 0a00 0000 0100 o World2......
两个字符串在内存中依次排列,并且指定的 30 字节长度跨越两个字符串,然后是一些字节。第一个字符串的正确长度为 12,第二个字符串的正确长度为 13。
这里可能值得一提的是,在处理 C API 时,您还应该使用
.asciz
而不是 .ascii
来让字符串以零结尾,但这在这里没有什么区别,因为您正在进行原始写入到文件描述符。