为何用rax寄存器存储uint64_t,却未用eax等32位寄存器处理int?
问题分析:为何uint64_t用寄存器存储而uint32_t直接入栈?
C代码片段
#include <cstdint> int main() { unsigned int i = 0x11111111; unsigned int j = 0xFFFFFFFF; uint64_t k = 0xFFFFFFFF11111111; }
对应的汇编代码
0000000140001000 sub rsp,18h 0000000140001004 mov dword ptr [rsp],11111111h 000000014000100B mov dword ptr [rsp+4],0FFFFFFFFh 0000000140001013 mov rax,0FFFFFFFF11111111h 000000014000101D mov qword ptr [rsp+8],rax 0000000140001022 xor eax,eax 0000000140001024 add rsp,18h 0000000140001028 ret
问题
观察到代码中使用rax寄存器承载uint64_t类型的值,但对于unsigned int类型的变量,并未使用eax等32位寄存器处理,而是直接将值存入栈中。请问为何处理8字节类型时使用对应长度的寄存器,处理4字节类型时却不使用对应长度的寄存器?
解答
这本质是x86-64指令集的特性和编译器代码大小优化共同作用的结果:
- 对于32位无符号整数,x86-64支持直接将32位立即数写入内存的单条指令,比如
mov dword ptr [rsp],11111111h。这条指令长度短、执行效率高,没必要多绕一步先把值放进eax寄存器再存到栈里——那样反而会多一条指令,增加代码体积。 - 对于64位无符号整数,x86-64的指令集没有直接将64位立即数写入内存的指令,只能先通过
mov rax,0FFFFFFFF11111111h把64位立即数加载到64位寄存器rax中,再用mov qword ptr [rsp+8],rax将寄存器里的值转存到栈内存。
内容的提问来源于stack exchange,提问作者rand_program
相关产品推荐
相关产品推荐

