我有以下指示:mov r1, r7
,但在查看反汇编代码后,我发现实际生成的代码是adds r1, r7, #0
我查阅了ARMv 6-M架构参考手册,发现有MOVS <Rd>,<Rm>
指令(A6.7.40),与ADDS
不同。
虽然这不是一个大问题,但我仍然感到困惑,为什么汇编程序会替换我用不同的操作码编写的代码。根据我正在阅读的书,所有的非跳转指令都需要1个周期(我宁愿汇编程序是愚蠢的,而不是试图为我优化一些东西)。
我正在使用Raspberry Pi皮科SDK,它使用GNU汇编程序AFAIK。
我所有的代码都是用helloworld.S写的,完整的源代码是:
.thumb_func
.global main
main:
mov r7, #0
bl stdio_init_all
loop:
ldr r0, =helloworld
add r7, #1
mov r1, r7
bl printf
mov r0, #250
bl sleep_ms
b loop
.data
.align 4
helloworld: .asciz "Hello World %d\n"
3条答案
按热度按时间rsaldnfx1#
您正在编写Thumb模式汇编代码,RPi皮科支持Thumb-2,这意味着实际输出将以UAL format显示。
如果参考ARMv6-M reference manual,表D4-1指定了前UAL Thumb语法到UAL语法的转换,特别是:
| UAL前Thumb语法|等效UAL语法|注意事项|
| - -----|- -----|- -----|
|
MOV <Rd>, <Rm>
|ADDS <Rd>, <Rm>, #0
|如果<Rd>
和<Rm>
都是R 0-R7。|| |
MOV <Rd>, <Rm>
|否则。|正如Tom所建议的那样,如果您想编写UAL代码(然后将实际按原样组装),可以添加
.syntax unified
。ttisahbt2#
我能否建议你补充:
在你档案的开头在此之后,您必须显式地为所有指令添加后缀,以标记它们是否设置了标志以及它们是否是有条件的,但您可能会发现显式地控制所使用的操作码会更容易。
下面是编译器资源管理器中的代码:https://godbolt.org/z/zo8nnc9sh
umuewwlo3#
Thumb指令是16位长,这不是很多位。由于 mov rx,ry 和 adds rx,ry,#0 都做同样的事情,而 adds rx,ry,#0 更通用,因此只支持 adds 版本,汇编程序将 mov 转换为 *adds”。所以 mov 本质上变成了伪指令。
其他国际审计准则也做类似的事情。RISC-V在RV 32 I伊萨中没有 mv 指令。它类似地编码为 addi。关键是保存操作码编码空间,一种有限的资源。