Analyzing a decompiled ARM binary, I came across these instructions
...
mov r7, #0
uxth r0, r7
...
add r7, r7, #1
uxth r4, r7
...
From ARM docs:
UXTH{cond} {Rd}, Rm {,rotation}
extends a 16-bit value to a 32-bit value. It does this by:
- Rotating the value from Rm right by 0, 8, 16, or 24 bits.
- Extracting bits[15:0] from the value obtained.
- Zero extending to 32 bits.
This really confused me and raised a lot of questions:
- Doesn't mov already operate on 32-bit registers ?
- What is the purpose of zero extending a zero using
uxth
? - Why not just load the value directly into r0 ?
CodePudding user response:
Correct me if I'm wrong, but it seems it's merely doing an AND
with 0xffff
.
uxth r4, r7
Let's apply the operations written in the manual in order.
1. Rotating the value from Rm right by 0, 8, 16, or 24 bits.
This is not set so no rotation.
2. Extracting bits[15:0] from the value obtained.
3. Zero extending to 32 bits.
These steps together is the same as & 0xffff
.
So basically it's & 0xffff
written in an unnecessarily complicated way. Oops, even the compiler generates this code so this seems to be the quite standard way to zero extend 16 bits in 32-bit ARM. Sorry for the misinformation.
mov r7, #0
uxth r0, r7
These lines are probably intentionally written in a complicated way, or it is from unoptimized compilation, or the compiler is so bad even with optimization. Just do mov r0, #0
.
Somehow uxth reads like ux