When looking at the assembly code, I don't quite understand what it means to shift operations in register_tm_clones. What is the role of the shift operation?
Comparing assembly code with source code, I thought I had understand the purpose of SUB RAX,6020F8H.The operation is related to the SIZE in source code.Becaause the value of SIZE is zero , I guessed the assembly code is the implement of (TMC_END - TMC_LIST).During debugging, I found that the FOR could only be executed once, or even skipped the size++ to execute the IF statement directly.
source code:
register_tm_clones (void)
{
void (*fn) (void *, size_t);
size_t size;
#ifdef HAVE_GAS_HIDDEN
size = (__TMC_END__ - __TMC_LIST__) / 2;
#else
for (size = 0; __TMC_LIST__[size * 2] != NULL; size++)
continue;
#endif
if (size == 0)
return;
fn = _ITM_registerTMCloneTable;
__asm ("" : "+r" (fn));
if (fn)
fn (__TMC_LIST__, size);
}
#endif /* USE_TM_CLONE_REGISTRY */
assembly code:
register_tm_clones proc near
mov eax, 6020F8h ;.bss
push rbp
sub rax, 6020F8h ;.bss
sar rax, 3
mov rbp, rsp ; return address
mov rdx, rax
shr rdx, 3Fh
add rax, rdx
sar rax, 1
jnz short loc_400C24
loc_400C22:
pop rbp
retn
loc_400C24:
mov edx, 0
test rdx, rdx
jz short loc_400C22
pop rbp
mov rsi, rax
mov edi, 6020F8h
jmp rdx
register_tm_clones endp
I would like to know the role of this assembly code for specific operation. Of course, the main still want to know the purpose of the shift operation here. If I can understand this, it's more possible for me to solve other problems. (Maybe I've had some mistakes in my previous understanding of the code, and I hope you can point it out)
The for
is not present in the assembly code. It is never seen by the compiler because it is removed by the preprocessor if HAVE_GAS_HIDDEN
is set which happens to be the case here.
The sar rax, 3
is due to pointer arithmetic, as the size of the items in the __TMC_LIST__
is 8 bytes, being 2^3.
The two other shifts are the signed division by two. It's implemented that way to follow the rounding rules for negative numbers. Of course that is not needed but the poor compiler does not know that __TMC_END__ - __TMC_LIST__ >= 0
.