Reverse Engineering for Beginners

(avery) #1

CHAPTER 47. STRINGS TRIMMING CHAPTER 47. STRINGS TRIMMING


je .L12
cmp cl, 13 ; is it '\r'?
je .L12
.L9:
; return "s"
mov rax, rbx
pop rbx
ret


Now this is more complex. The code before the loop’s body start is executed only once, but it has theCR/LFcharacters
check too! What is this code duplication for?


The common way to implement the main loop is probably this:



  • (loop start) check forCR/LFcharacters, make decisions

  • store zero character


But GCC has decided to reverse these two steps. Of course,store zero charactercannot be first step, so another check is
needed:



  • workout first character. match it toCR/LF, exit if character is notCR/LF

  • (loop begin) store zero character

  • check forCR/LFcharacters, make decisions


Now the main loop is very short, which is good for modernCPUs.


The code doesn’t use the str_len variable, but str_len-1. So this is more like an index in a buffer. Apparently, GCC notices
that the str_len-1 statement is used twice. So it’s better to allocate a variable which always holds a value that’s smaller
than the current string length by one, and decrement it (this is the same effect as decrementing the str_len variable).


47.4 ARM64: Non-optimizing GCC (Linaro) 4.9


This implementation is straightforward:


Listing 47.4: Non-optimizing GCC (Linaro) 4.9

str_trim:
stp x29, x30, [sp, -48]!
add x29, sp, 0
str x0, [x29,24] ; copy input argument into local stack
ldr x0, [x29,24] ; s
bl strlen
str x0, [x29,40] ; str_len variable in local stack
b .L2
; main loop begin
.L5:
ldrb w0, [x29,39]
; W0=c
cmp w0, 13 ; is it '\r'?
beq .L3
ldrb w0, [x29,39]
; W0=c
cmp w0, 10 ; is it '\n'?
bne .L4 ; goto exit if it is not
.L3:
ldr x0, [x29,40]
; X0=str_len
sub x0, x0, #1
; X0=str_len-1
ldr x1, [x29,24]
; X1=s
add x0, x1, x0
; X0=s+str_len-1
strb wzr, [x0] ; write byte at s+str_len-1
; decrement str_len:
ldr x0, [x29,40]
; X0=str_len
sub x0, x0, #1
; X0=str_len-1

Free download pdf