3.10. STRING TO NUMBER CONVERSION (ATOI())
The compilers do this often, so it’s important to recognize these tricks.
Another example of it in this book:3.16.1 on page 535.
Optimizing MSVC 2013 x64 does the same tricks.
Optimizing Keil 6/2013 (ARM mode)
Listing 3.28: 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 theCMPinstruction (at line 29) has been “Not Equal” (hence-NEsuffix).
So whatRSBNEdoes 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.
3.10.3 Exercise
Oh, by the way, security researchers deals often with unpredictable behavior of program while handling
of incorrect data.
For example, while fuzzing. As an exercise, you may try to enter non-digit characters and see what
happens.