没有GCC为什么产生MOV EAX%,%EAX什么意思呢? [英] Why did GCC generate mov %eax,%eax and what does it mean?
问题描述
GCC 4.4.3生成以下x86_64的组装。这混淆我的部分是 MOV EAX%,%EAX
。移动寄存器本身呢?为什么呢?
GCC 4.4.3 generated the following x86_64 assembly. The part that confuses me is the mov %eax,%eax
. Move the register to itself? Why?
23b6c: 31 c9 xor %ecx,%ecx ; the 0 value for shift
23b6e: 80 7f 60 00 cmpb $0x0,0x60(%rdi) ; is it shifted?
23b72: 74 03 je 23b77
23b74: 8b 4f 64 mov 0x64(%rdi),%ecx ; is shifted so load shift value to ecx
23b77: 48 8b 57 38 mov 0x38(%rdi),%rdx ; map base
23b7b: 48 03 57 58 add 0x58(%rdi),%rdx ; plus offset to value
23b7f: 8b 02 mov (%rdx),%eax ; load map_used value to eax
23b81: 89 c0 mov %eax,%eax ; then what the heck is this? promotion from uint32 to 64-bit size_t?
23b83: 48 d3 e0 shl %cl,%rax ; shift rax/eax by cl/ecx
23b86: c3 retq
C ++的code此功能是:
The C++ code for this function is:
uint32_t shift = used_is_shifted ? shift_ : 0;
le_uint32_t le_map_used = *used_p();
size_t map_used = le_map_used;
return map_used << shift;
这是 le_uint32_t
是包裹在大端机字节交换操作的类。在x86它什么都不做。在 used_p()
函数计算从地图基础指针+偏移量并返回正确类型的指针。
An le_uint32_t
is a class which wraps byte-swap operations on big-endian machines. On x86 it does nothing. The used_p()
function computes a pointer from the map base + offset and returns a pointer of the correct type.
推荐答案
在X86-64 32位指令隐含零扩展:位32-63被清除。所以有时候这就是为什么你会看到古怪的指令。
In x86-64, 32-bit instructions implicitly zero-extend: bits 32-63 are cleared. So sometimes thats why you'll see odd-looking instructions.
不过,previous MOV
也是32位的,所以高半%RAX
的被清除。在 MOV EAX%,%EAX
看起来是一个NOP。
However, the previous mov
is also 32-bit, so the high half of %rax
is already cleared. The mov %eax,%eax
appears to be a NOP.
这篇关于没有GCC为什么产生MOV EAX%,%EAX什么意思呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!