Reverse Engineering for Beginners

(avery) #1
CHAPTER 42. STRING TO NUMBER CONVERSION (ATOI()) CHAPTER 42. STRING TO NUMBER CONVERSION (ATOI())
If the “minus” sign was encountered at the string start, the NEG instruction is to be executed at the end. It just negates the
number.

There is one more thing that needs mentioning. How would a common programmer check if the character is not a digit?
Just how we have it in the source code:
if (*s<'0' || *s>'9')

There are two comparison operations. What is interesting is that we can replace both operations by single one: just subtract
“0” from character value, treat result as unsigned value (this is important) and check if it’s greater than 9.

For example, let’s say that the user input contains the dot character (“.”) which hasASCIIcode 46. 46 −48 =− 2 if we treat
the result as a signed number. Indeed, the dot character is located two places earlier than the “0” character in theASCII
table. But it is0xFFFFFFFE(4294967294) if we treat the result as an unsigned value, and that’s definitely bigger than 9!

The compilers do this often, so it’s important to recognize these tricks.

Another example of it in this book:48.1.2 on page 510.

Optimizing MSVC 2013 x64 does the same tricks.

42.2.2 Optimizing Keil 6/2013 (ARM mode)


Listing 42.7: Optimizing Keil 6/2013 (ARM mode)
1 my_atoi PROC
2 PUSH {r4-r6,lr}
3 MOV r4,r0
4 LDRB r0,[r0,#0]
5 MOV r6,#0
6 MOV r5,r6
7 CMP r0,#0x2d '-'
8 ; R6 will contain 1 if minus was encountered, 0 if otherwise
9 MOVEQ r6,#1
10 ADDEQ r4,r4,#1
11 B |L0.80|
12 |L0.36|
13 SUB r0,r1,#0x30
14 CMP r0,#0xa
15 BCC |L0.64|
16 ADR r0,|L0.220|
17 BL __2printf
18 MOV r0,#0
19 BL exit
20 |L0.64|
21 LDRB r0,[r4],#1
22 ADD r1,r5,r5,LSL #2
23 ADD r0,r0,r1,LSL #1
24 SUB r5,r0,#0x30
25 |L0.80|
26 LDRB r1,[r4,#0]
27 CMP r1,#0
28 BNE |L0.36|
29 CMP r6,#0
30 ; negate result
31 RSBNE r0,r5,#0
32 MOVEQ r0,r5
33 POP {r4-r6,pc}
34 ENDP
35
36 |L0.220|
37 DCB "Error! Unexpected char: '%c'\n",0


There is no NEG instruction in 32-bit ARM, so the “Reverse Subtraction” operation (line 31) is used here. It is triggered if the
result of the CMP instruction (at line 29) was “Not Equal” (hence -NE suffix). So what RSBNE does is to subtract the resulting
value from 0. It works just like the regular subtraction operation, but swaps operands. Subtracting any number from 0
results in negation: 0 −x=−x.

Thumb mode code is mostly the same.

GCC 4.9 for ARM64 can use the NEG instruction, which is available in ARM64.
Free download pdf