1.17. MORE ABOUT STRINGS
Perhaps it is simpler for GCC’s code generator torememberthe whole 32-bitEDXregister is allocated for
acharvariable and it then can be sure that the highest bits has no any noise at any point.
After that we also see a new instruction—NOT. This instruction inverts all bits in the operand.
You can say that it is a synonym to theXOR ECX, 0ffffffffhinstruction. NOTand the followingADD
calculate the pointer difference and subtract 1, just in a different way. At the startECX, where the pointer
tostris stored, gets inverted and 1 is subtracted from it.
See also: “Signed number representations” (2.2 on page 452).
In other words, at the end of the function just after loop body, these operations are executed:
ecx=str;
eax=eos;
ecx=(-ecx)-1;
eax=eax+ecx
return eax
... and this is effectively equivalent to:
ecx=str;
eax=eos;
eax=eax-ecx;
eax=eax-1;
return eax
Why did GCC decide it would be better? Hard to guess. But perhaps the both variants are equivalent in
efficiency.
ARM
32-bit ARM
Non-optimizing Xcode 4.6.3 (LLVM) (ARM mode)
Listing 1.184: Non-optimizing Xcode 4.6.3 (LLVM) (ARM mode)
_strlen
eos = -8
str = -4
SUB SP, SP, #8 ; allocate 8 bytes for local variables
STR R0, [SP,#8+str]
LDR R0, [SP,#8+str]
STR R0, [SP,#8+eos]
loc_2CB8 ; CODE XREF: _strlen+28
LDR R0, [SP,#8+eos]
ADD R1, R0, #1
STR R1, [SP,#8+eos]
LDRSB R0, [R0]
CMP R0, #0
BEQ loc_2CD4
B loc_2CB8
loc_2CD4 ; CODE XREF: _strlen+24
LDR R0, [SP,#8+eos]
LDR R1, [SP,#8+str]
SUB R0, R0, R1 ; R0=eos-str
SUB R0, R0, #1 ; R0=R0-1
ADD SP, SP, #8 ; free allocated 8 bytes
BX LR
Non-optimizing LLVM generates too much code, however, here we can see how the function works with
local variables in the stack. There are only two local variables in our function:eosandstr. In this listing,
generated byIDA, we have manually renamedvar_8andvar_4toeosandstr.