我对 ARM 程序集很陌生,我已经看到 bang ( !
) 用于在寻址模式语法中的计算后真正更新寄存器,但我无法弄清楚之间的语义差异是什么(这个输出是fromobjdump
所以它使用gas
语法):
ldm r4!, {r0, r1, r2, r3}
和:
ldm r4, {r0, r1, r2, r3}
任何的想法 ?
我对 ARM 程序集很陌生,我已经看到 bang ( !
) 用于在寻址模式语法中的计算后真正更新寄存器,但我无法弄清楚之间的语义差异是什么(这个输出是fromobjdump
所以它使用gas
语法):
ldm r4!, {r0, r1, r2, r3}
和:
ldm r4, {r0, r1, r2, r3}
任何的想法 ?
的!
表示写回基址寄存器的。基址寄存器是用于寻址要读取或写入的内存的寄存器 - 在您的情况下它是R4
. 写回意味着基址寄存器将被更新,增量等于传输数据的大小。
所以,指令
ldm r4!, {r0, r1, r2, r3}
可以用以下伪代码表示:
r0 = *(int)(r4)
r1 = *(int)(r4+4)
r2 = *(int)(r4+8)
r3 = *(int)(r4+12)
r4 = r4 + 16 // writeback (16 bytes transferred)
在没有!
写回的变体中不会发生,所以R4
保留了原始值。
在LDR
和STR
说明中,您可能还会遇到预索引和后索引符号:
LDR R0, [R4, #4] ; simple offset: R0 = *(int*)(R4+4); R4 unchanged
LDR R0, [R4, #4]! ; pre-indexed: R0 = *(int*)(R4+4); R4 = R4+4
LDR R0, [R4], #4 ; post-indexed: R0 = *(int*)(R4+0); R4 = R4+4
有关详细信息,请参阅ARM 汇编程序指南。