我是ARM 64汇编的新手(来自x86世界)。假设以下指令:
adr x1,_data ldrb w0, [x1]
我期待寄存器“w 0”(32位宽)填充为零,只有最低字节填充为从内存读取的字节。我可以看到来自X 0的高32位也填充为零!我没有想到!:)那么,ldrb w0, [x1]的意义是什么呢?和ldrb x0, [x1]不一样吗?谢谢!
ldrb w0, [x1]
ldrb x0, [x1]
yrefmtwq1#
一般而言,写入32位寄存器wN的 * 每个 * ARM64指令也会将对应的64位寄存器xN的高半部分置零。这可以避免输入依赖于目标寄存器,或需要进行部分寄存器重命名。在ldrb w0, [x1]的情况下,这意味着您可以免费将零扩展到x0。如果从内存加载的字节被视为无符号8位整数,则x0的相关部分会自动包含正确的值,以将其视为无符号16、32或64位整数。因此,不需要单独的ldrb x0, [x1]助记符。并且实际上汇编器将拒绝它。如果你想要符号扩展,那么就有区别了。如果内存中的字节是0xa5,那么ldrsb w0, [x1]将用0xffffffa5填充w0,并将高半部分置零,这样x0就包含了0x00000000ffffffa5。另一方面,ldrsb x0, [x1]将扩展到整个64位寄存器。留下含有0xffffffffffffffa5的x0。
wN
xN
x0
0xa5
ldrsb w0, [x1]
0xffffffa5
w0
0x00000000ffffffa5
ldrsb x0, [x1]
0xffffffffffffffa5
1条答案
按热度按时间yrefmtwq1#
一般而言,写入32位寄存器
wN
的 * 每个 * ARM64指令也会将对应的64位寄存器xN
的高半部分置零。这可以避免输入依赖于目标寄存器,或需要进行部分寄存器重命名。在
ldrb w0, [x1]
的情况下,这意味着您可以免费将零扩展到x0
。如果从内存加载的字节被视为无符号8位整数,则x0的相关部分会自动包含正确的值,以将其视为无符号16、32或64位整数。因此,不需要单独的ldrb x0, [x1]
助记符。并且实际上汇编器将拒绝它。如果你想要符号扩展,那么就有区别了。如果内存中的字节是
0xa5
,那么ldrsb w0, [x1]
将用0xffffffa5
填充w0
,并将高半部分置零,这样x0
就包含了0x00000000ffffffa5
。另一方面,ldrsb x0, [x1]
将扩展到整个64位寄存器。留下含有0xffffffffffffffa5
的x0
。