Reverse Engineering
<dennis(a)yurichev.com>
cbn d
2013-2015, .
Creative Commons Attribution-NonCommercial-NoDerivs
( ) 3.0 .
, http://creativecommons.org/licenses/by-nc-nd/3.0/.
(14 2015 .).
( ) beginners.re.
.
LITE- ( ),
reverse engineering: beginners.re
twitter : @yurichev1 ,
2 .
: facebook.
1 twitter.com/yurichev
2 yurichev.com
i
, !
http://beginners.re/survey.html
ii
I 1
II 469
III 478
IV Java 628
V 665
VI 688
VII 742
3
VIII RE - 748
IX (proprietary) 862
X 894
XI 912
XII 916
954
956
996
3 Reverse Engineering
iii
0.0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi
I 1
1 CPU 3
1.1 ISA4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 5
2.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.1 - MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3 Hello, world! 7
3.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.2 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.1.3 GCC: AT&T . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2 x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.1 MSVC x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.2 GCC x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 GCC - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4.1 Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.2 Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4.3 Xcode 4.6.3 (LLVM) ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4.4 Xcode 4.6.3 (LLVM) ( Thumb-2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.4.5 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.5 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5.1 (global pointer) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5.2 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5.3 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.5.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.5.5 GCC: GDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.7.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.7.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4 24
4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5 25
5.1 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
5.2 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5.2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.2.4 x86: alloca() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.2.5 (Windows) SEH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.2.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4 Instruction Set Architecture ( )
iv
5.2.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.5.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.5.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
6 printf() 37
6.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.1.1 x86: 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.1.2 x64: 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
6.2.1 ARM: 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
6.2.2 ARM: 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
6.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.3.1 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.3.2 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7 scanf() 61
7.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.1.2 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
7.1.3 MSVC + OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
7.1.4 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
7.1.5 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
7.1.6 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
7.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
7.2.1 MSVC: x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
7.2.2 MSVC: x86 + OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.2.3 GCC: x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
7.2.4 MSVC: x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
7.2.5 ARM: Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
7.2.6 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
7.2.7 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
7.3 scanf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
7.3.1 MSVC: x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
7.3.2 MSVC: x86: IDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.3.3 MSVC: x86 + OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.3.4 MSVC: x86 + Hiew . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.3.5 MSVC: x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.3.6 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.3.7 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.3.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.4.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
8 91
8.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
8.1.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
8.1.2 MSVC + OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
8.1.3 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
8.2 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
8.2.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
8.2.2 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
8.2.3 GCC: uint64_t int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
8.3 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
8.3.1 Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
8.3.2 Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.3.3 Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.3.4 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.4 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
v
9 101
9.1 void . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
9.2 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
9.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
10 104
10.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
10.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
10.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
11 GOTO 114
11.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
11.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
12 118
12.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
12.1.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
12.1.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
12.1.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
12.2.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
12.2.2 Keil 6/2013: Thumb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
12.2.3 Keil 6/2013: ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
12.2.4 GCC 4.9 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
12.2.5 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
12.2.6 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
12.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
12.3.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
12.3.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
12.3.3 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
12.3.4 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
12.3.5 , if/else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
12.3.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
12.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
12.4.1 32-bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
12.4.2 64-bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
12.4.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
12.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
12.5.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
12.5.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
12.5.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
12.5.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
12.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
13 switch()/case/default 147
13.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
13.1.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
13.1.2 ARM: Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
13.1.3 ARM: Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
13.1.4 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
13.1.5 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
13.1.6 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
13.1.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
13.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
13.2.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
13.2.2 ARM: Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
13.2.3 ARM: Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
13.2.4 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
13.2.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
13.3 case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
13.3.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
13.3.2 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
13.3.3 ARM64: GCC 4.9.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
13.4 Fall-through . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
13.4.1 MSVC x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
vi
13.4.2 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
13.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
13.5.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
14 178
14.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
14.1.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
14.1.2 x86: OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
14.1.3 x86: tracer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
14.1.4 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
14.1.5 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
14.1.6 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
14.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
14.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
14.2.2 ARM ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
14.2.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
14.2.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
14.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
14.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
14.4.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
14.4.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
14.4.3 #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
14.4.4 #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
15 - 197
15.1 strlen() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
15.1.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
15.1.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
15.1.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
15.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
15.2.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
16 210
16.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
16.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
16.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
16.1.3 , . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
16.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
16.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
16.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
16.3.1 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
17 FPU 217
17.1 IEEE 754 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
17.2 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
17.3 ARM, MIPS, x86/x64 SIMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
17.4 /++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
17.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
17.5.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
17.5.2 ARM: Xcode 4.6.3 (LLVM) ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
17.5.3 ARM: Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
17.5.4 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
17.5.5 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
17.5.6 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
17.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
17.6.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
17.6.2 ARM + Xcode 4.6.3 (LLVM) ( Thumb-2) . . . . . . . . . . . . . . . . . . . . . . . 229
17.6.3 ARM + Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
17.6.4 ARM64 + GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
17.6.5 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
17.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
17.7.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
17.7.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
17.7.3 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
17.7.4 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
vii
17.8 , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
17.9 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
17.10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
17.10.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
17.10.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
18 267
18.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
18.1.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
18.1.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
18.1.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
18.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
18.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
18.2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
18.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
18.3.1 Xcode 4.6.3 (LLVM) ( Thumb-2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
18.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
18.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
18.5.1 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
18.5.2 32- ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
18.5.3 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
18.5.4 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
18.5.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
18.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
18.6.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
18.6.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
18.6.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
18.6.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
18.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
18.7.1 32-bit ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
18.7.2 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
18.7.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
18.7.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
18.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
18.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
18.9.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
18.9.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
18.9.3 #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
18.9.4 #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
18.9.5 #5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
19 316
19.1 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
19.1.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
19.1.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
19.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
19.2.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
19.2.2 ARM + Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
19.2.3 ARM + Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
19.2.4 ARM + Xcode 4.6.3 (LLVM) ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
19.2.5 ARM: BIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
19.2.6 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
19.2.7 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
19.2.8 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
19.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
19.4 : FPU5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
19.4.1 - XOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
19.4.2 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
19.4.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
19.4.4 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
19.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
19.5.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
19.5.2 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
5 Floating-point unit
viii
19.5.3 ARM + Xcode 4.6.3 (LLVM) ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
19.5.4 ARM + Xcode 4.6.3 (LLVM) ( Thumb-2) . . . . . . . . . . . . . . . . . . . . . . . . . 344
19.5.5 ARM64 + GCC 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
19.5.6 ARM64 + GCC 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
19.5.7 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
19.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
19.6.1 ( ) . . . . . . . . . . . . . . . . . . . . . 347
19.6.2 ( ) . . . . . . . . . . . . . . . . . . . . . . 347
19.6.3 ( ) . . . . . . . . . . . . . . . . . . . . . 348
19.6.4 ( ) . . . . . . . . . . . . . . . . . . . . . . 348
19.6.5 ( ) . . . . . . . . . . . . . . . . . . . . . . . . 348
19.6.6 ( ) . . . . . . . . . . . . . . . . . . . . . . . . . 349
19.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
19.7.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
19.7.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
19.7.3 #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
19.7.4 #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
20 356
20.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
20.2 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
20.3 32-bit ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
20.4 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
20.4.1 MIPS (relocs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
20.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
21 362
21.1 MSVC: SYSTEMTIME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
21.1.1 OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
21.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
21.2 malloc() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
21.3 UNIX: struct tm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
21.3.1 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
21.3.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
21.3.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
21.3.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
21.3.5 32- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
21.3.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
21.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
21.4.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
21.4.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
21.4.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
21.4.4 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
21.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
21.5.1 OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
21.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
21.6.1 CPUID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
21.6.2 oat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
21.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
21.7.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
21.7.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
22 (union) 398
22.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
22.1.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
22.1.2 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
22.1.3 ARM ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
22.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
22.2.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
22.2.2 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
22.2.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
22.2.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
22.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
ix
23 406
23.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
23.1.1 MSVC + OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
23.1.2 MSVC + tracer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
23.1.3 MSVC + tracer (code coverage) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
23.2 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
23.2.1 GCC + GDB ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
23.2.2 GCC + GDB ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
25 SIMD 429
25.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
25.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
25.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
25.2 strlen() SIMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
26 64 443
26.1 x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
26.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
26.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
27 SIMD 451
27.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
27.1.1 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
27.1.2 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
27.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459
27.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
27.3.1 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
27.3.2 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
27.4 : x64 SIMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
27.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
27.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
28 - ARM 464
28.1 (#) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
28.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
28.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
28.3.1 32- ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
28.3.2 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
28.4 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
29 - MIPS 468
29.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
29.2 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
x
II 469
30 471
31 Endianness ( ) 473
31.1 Big-endian ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
31.2 Little-endian ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
31.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
31.4 Bi-endian ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
31.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
32 475
33 CPU 476
33.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
33.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
34 - 477
34.1 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
III 478
35 479
35.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
35.1.1 MSVC 2012 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
35.1.2 MSVC 2012 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
35.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
36 484
36.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
36.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
36.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
37 CRC32 491
38 494
38.1 calc_network_address() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
38.2 form_IP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
38.3 print_as_IP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
38.4 form_netmask() set_bit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
38.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499
39 : 500
39.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
39.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
39.3 Intel C++ 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
41 9 508
41.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
41.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
41.2.1 Xcode 4.6.3 (LLVM) ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
41.2.2 Xcode 4.6.3 (LLVM) ( Thumb-2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
41.2.3 Xcode 4.6.3 (LLVM) Keil 6/2013 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
41.3 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
41.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
41.4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
41.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
41.5.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
41.5.2 #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
41.6 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
42 (atoi()) 515
42.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
xi
42.1.1 MSVC 2013 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
42.1.2 GCC 4.9.1 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
42.1.3 Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
42.1.4 Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
42.1.5 GCC 4.9.1 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
42.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
42.2.1 GCC 4.9.1 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
42.2.2 Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
42.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
43 Inline- 522
43.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
43.1.1 strcmp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
43.1.2 strlen() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
43.1.3 strcpy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
43.1.4 memset() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
43.1.5 memcpy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
43.1.6 memcmp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
43.1.7 IDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
45 abs() 534
45.1 GCC 4.9.1 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
45.2 GCC 4.9 ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
46 (variadic) 536
46.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
46.1.1 cdecl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
46.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
46.2 vprintf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
47 541
47.1 x64: MSVC 2013 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
47.2 x64: GCC 4.9.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
47.3 x64: GCC 4.9.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
47.4 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
47.5 ARM64: GCC (Linaro) 4.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
47.6 ARM: Keil 6/2013 ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
47.7 ARM: Keil 6/2013 ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
47.8 MIPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
48 toupper() 550
48.1 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
48.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
48.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
48.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
48.2.1 GCC ARM64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
48.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
49 554
49.1 (x86) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
49.2 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
50 559
50.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
50.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
50.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
50.2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
50.2.3 / . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
50.2.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
50.2.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
50.3 / - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
50.4 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
50.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
xii
50.5.1 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
51 ++ 563
51.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
51.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
51.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
51.1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
51.1.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
51.1.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
51.2 ostream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
51.3 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
51.4 STL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
51.4.1 std::string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
51.4.2 std::list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
51.4.3 std::vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
51.4.4 std::map std::set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
52 614
IV Java 628
54 Java 629
54.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
54.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
54.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633
54.4 JVM6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636
54.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636
54.6 beep() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638
54.7 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638
54.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639
54.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
54.10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642
54.11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643
54.12switch() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645
54.13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646
54.13.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646
54.13.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647
54.13.3 main() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647
54.13.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648
54.13.5 - (variadic) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
54.13.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651
54.13.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652
54.13.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
54.14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
54.14.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
54.14.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654
54.15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
54.16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 658
54.17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660
54.17.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660
54.17.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
54.18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664
6 Java virtual machine
7
xiii
V 665
55 667
55.1 Microsoft Visual C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
55.1.1 Name mangling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
55.2 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
55.2.1 Name mangling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
55.2.2 Cygwin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
55.2.3 MinGW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
55.3 Intel FORTRAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
55.4 Watcom, OpenWatcom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
55.4.1 Name mangling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
55.5 Borland . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
55.5.1 Delphi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
55.6 DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669
56 (win32) 670
56.1 Windows API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
56.2 tracer: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671
57 672
57.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672
57.1.1 /++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672
57.1.2 Borland Delphi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672
57.1.3 Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673
57.1.4 Base64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
57.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
57.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
58 assert() 677
59 678
59.1 Magic numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 678
59.1.1 DHCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
59.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
60 680
61 682
61.1 XOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
61.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
63 685
63.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685
63.2 ++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685
63.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685
63.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686
63.4.1 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687
63.4.2 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687
VI 688
64 689
64.1 cdecl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
64.2 stdcall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
64.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690
64.3 fastcall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690
64.3.1 GCC regparm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
64.3.2 Watcom/OpenWatcom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
64.4 thiscall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
64.5 x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
64.5.1 Windows x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
64.5.2 Linux x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694
xiv
64.6 oat, double . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694
64.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694
64.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695
66 (syscall-) 702
66.1 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
66.2 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703
67 Linux 704
67.1 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
67.1.1 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706
67.2 LD_PRELOAD Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706
68 Windows NT 709
68.1 CRT (win32) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
68.2 Win32 PE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
68.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
68.2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
68.2.3 Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
68.2.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
68.2.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714
68.2.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714
68.2.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715
68.2.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
68.2.9 .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
68.2.10TLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
68.2.11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
68.2.12Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
68.3 Windows SEH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
68.3.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
68.3.2 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723
68.3.3 Windows x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736
68.3.4 SEH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739
68.4 Windows NT: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 740
VII 742
69 743
69.1 IDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743
70 744
70.1 OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744
70.2 GDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744
70.3 tracer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744
71 745
71.0.1 strace / dtruss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745
72 746
73 747
xv
76 (Windows XP) 758
76.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762
77 + SMT- Z3 763
77.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 763
77.2 Z3 SMT- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766
78 771
78.1 #1: MacOS Classic PowerPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
78.2 #2: SCO OpenServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 778
78.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 785
78.3 #3: MS-DOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
79 QR9: , 793
80 SAP 820
80.1 SAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 820
80.2 SAP 6.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830
82 847
82.1 EICAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847
83 849
83.1 10 PRINT CHR$(205.5+RND(1)); : GOTO 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849
83.1.1 42- Trixter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849
83.1.2 Trixter: 27 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 850
83.1.3 . . . . . . . . . . . . . . . 850
83.1.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 851
83.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852
83.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853
83.2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 858
83.2.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860
IX (proprietary) 862
84 XOR- 863
84.1 Norton Guide: XOR- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 864
84.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 865
84.2 XOR- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867
84.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 870
85 Millenium 871
X 894
88 npad 895
89 897
89.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 897
89.2 x86- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 897
91 899
xvi
92 OpenMP 900
92.1 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902
92.2 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
93 Itanium 906
94 8086 909
XI 912
96 913
96.1 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
96.2 /++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
96.3 x86 / x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
96.4 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
96.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
97 914
97.1 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914
98 915
XII 916
99 1 919
99.1 1.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 919
100 2 920
100.1 2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 920
100.1.1 MSVC 2010 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 920
100.1.2 MSVC 2012 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921
100.2 2.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921
100.2.1 MSVC 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921
100.2.2GCC 4.4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 922
100.2.3 Keil ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 923
100.2.4 Keil ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 924
100.2.5 GCC 4.9.1 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 924
100.2.6 GCC 4.4.5 (MIPS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925
100.3 2.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 926
100.3.1 MSVC 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 926
100.3.2 Keil ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
100.3.3 Keil ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
100.3.4 GCC 4.9.1 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 928
100.3.5 GCC 4.4.5 (MIPS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929
100.4 2.13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929
100.4.1 MSVC 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929
100.4.2Keil ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
100.4.3Keil ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
100.4.4 GCC 4.9.1 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
100.4.5 GCC 4.4.5 (MIPS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
100.5 2.14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931
100.5.1MSVC 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931
100.5.2Keil ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932
100.5.3GCC 4.6.3 for Raspberry Pi ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932
100.5.4 GCC 4.9.1 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 933
100.5.5 GCC 4.4.5 (MIPS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934
100.6 2.15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
100.6.1 MSVC 2012 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
100.6.2 GCC 4.4.6 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938
100.6.3 GCC 4.8.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938
100.6.4Keil ( ARM): Cortex-R4F . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 939
xvii
100.6.5 GCC 4.9.1 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 940
100.6.6 GCC 4.4.5 (MIPS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 941
100.7 2.16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942
100.7.1 MSVC 2012 x64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942
100.7.2 Keil ( ARM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 943
100.7.3 Keil ( Thumb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 943
100.7.4 GCC 4.9.1 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 943
100.7.5 GCC 4.9.1 (ARM64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944
100.7.6 GCC 4.4.5 (MIPS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 947
100.8 2.17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948
100.9 2.18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948
100.10
2.19 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948
100.11
2.20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948
101 3 950
101.1 3.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950
101.2 3.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950
101.3 3.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950
101.4 3.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950
101.5 3.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951
101.6 3.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951
954
103? 954
956
A x86 956
A.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956
A.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956
A.2.1 RAX/EAX/AX/AL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956
A.2.2 RBX/EBX/BX/BL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957
A.2.3 RCX/ECX/CX/CL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957
A.2.4 RDX/EDX/DX/DL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957
A.2.5 RSI/ESI/SI/SIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957
A.2.6 RDI/EDI/DI/DIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957
A.2.7 R8/R8D/R8W/R8L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957
A.2.8 R9/R9D/R9W/R9L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
A.2.9 R10/R10D/R10W/R10L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
A.2.10 R11/R11D/R11W/R11L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
A.2.11 R12/R12D/R12W/R12L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
A.2.12 R13/R13D/R13W/R13L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
A.2.13 R14/R14D/R14W/R14L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
A.2.14 R15/R15D/R15W/R15L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
A.2.15 RSP/ESP/SP/SPL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 959
A.2.16 RBP/EBP/BP/BPL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 959
A.2.17 RIP/EIP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 959
A.2.18 CS/DS/ES/SS/FS/GS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 959
A.2.19 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 959
A.3 FPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 960
A.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 960
A.3.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961
A.3.3 Tag Word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961
A.4 SIMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962
A.4.1 MMX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962
A.4.2 SSE AVX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962
A.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962
A.5.1 DR6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962
A.5.2 DR7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962
A.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 963
xviii
A.6.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 963
A.6.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 964
A.6.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968
A.6.4 FPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 972
A.6.5 ASCII- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 973
B ARM 975
B.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975
B.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975
B.3 32- ARM (AArch32) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975
B.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975
B.3.2 Current Program Status Register (CPSR) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 976
B.3.3 VPF ( ) NEON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 976
B.4 64- ARM (AArch64) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 976
B.4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 976
B.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 977
B.5.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 977
C MIPS 978
C.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978
C.1.1 GPR8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978
C.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . 978
C.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978
C.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 979
D GCC 980
E MSVC 981
F Cheatsheets 982
F.1 IDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982
F.2 OllyDbg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982
F.3 MSVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983
F.4 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983
F.5 GDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983
G 985
G.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 985
G.1.1 Hello, world! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 985
G.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 985
G.1.3 scanf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
G.1.4 switch()/case/default . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
G.1.5 #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
G.1.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
G.1.7 #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
G.1.8 #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 987
G.1.9 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 987
G.1.10 . . . . . . . . . . . . . . . . . . . . . . . . . 987
G.1.11 FPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 987
G.1.12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 988
G.1.13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 989
G.1.14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 990
G.1.15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 991
G.1.16 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 991
G.2 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
G.2.1 1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
G.2.2 1.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
G.3 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
G.3.1 2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
G.3.2 2.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
G.3.3 2.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
G.3.4 2.13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
G.3.5 2.14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
G.3.6 2.15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
8 General Purpose Registers ( )
xix
G.3.7 2.16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
G.3.8 2.17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
G.3.9 2.18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
G.3.10 2.19 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
G.3.11 2.20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.4 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.4.1 3.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.4.2 3.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.4.3 3.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.4.4 3.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.4.5 3.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.4.6 3.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
G.5.1 (Windows XP) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994
996
1000
1002
xx
reverse engineering : 1) ; 2) -
; 3) .
.
Oracle RDBMS (81 (. 834)), Itanium (93 (. 906)), (78 (. 771)), LD_PRELOAD (67.2
(. 706)), , ELF9 , PE win32 (68.2 (. 712)), x86-64 (26.1 (. 443)),
(68.4 (. 740)), (66 (. 702)), TLS10 , - (PIC11 ) (67.1 (. 704)), prole-
guided optimization (95.1 (. 910)), C++ STL (51.4 (. 580)), OpenMP (92 (. 900)), SEH (68.3 (. 718)).
reverse engineer . -
: dennis(a)yurichev.com, Skype: dennis.yurichev.
, : herm1t , Avid .
, : Beaver , , Shell
Rocket, Zhu Ruijin, Changmin Heo.
: , Arnaud Patard (rtp #debian-arm IRC), .
: Archer.
: Byungho Min.
: Lstar , , , Logxen , Yuan Jochen Kang,
Mal Malakov, Lewis Porter.
.
: .
github.com .
LATEX. .
9 , Linux *NIX
10 Thread Local Storage
11 Position Independent Code: 67.1 (. 704)
xxi
0.0.1.
, () .
, , 12 (LaTeX),
.
.
: PLANS13 .
, , .
http://yurichev.com/donate.html.
!
http://yurichev.com/donors.html.
mini-
Q: ?
A: 14 , : -
15 . , CPU16
. - ,
: 1) malware () ; 2) -
. , ,
, , , .
Q: PDF-, ?
A: Adobe Acrobat Reader Alt+LeftArrow.
Q: ! ?
A: lite-: http://beginners.re/#lite.
Q: , reverse engineering-.
A: , LITE- 1-2 .
Q: ? ?
A: , Creative Commons. -
, .
Q: .
A: .
Q: reverse engineer-?
A: reddit, RE17 , hiring thread (2013 Q3, 2014). .
netsec : 2014 Q2.
Q: ?
A: : ; .
Q: ...
A: (dennis(a)yurichev.com) : forum.yurichev.com.
Reverse Engineering
Its very well done .. and for free .. amazing.18 Daniel Bilar, Siege Technologies, LLC.
12 github.com/dennis714/RE-for-beginners
13 github.com/dennis714/RE-for-beginners/blob/master/PLANS
14
15 : [Fog13b]
16 Central processing unit
17 reddit.com/r/ReverseEngineering/
18 twitter.com/daniel_bilar/status/436578617221742593
xxii
... excellent and free19 Pete Finnigan, Oracle RDBMS.
... book is interesting, great job! Michael Sikorski, Practical Malware Analysis: The Hands-On Guide to
Dissecting Malicious Software.
... my compliments for the very nice tutorial! Herbert Bos, Vrije Universiteit Amsterdam,
Modern Operating Systems (4th Edition).
... It is amazing and unbelievable. Luis Rocha, CISSP / ISSAP, Technical Manager, Network & Information Security at
Verizon Business.
Thanks for the great work and your book. Joris van de Vis, SAP Netweaver & Security.
... reasonable intro to some of the techniques.20 Mike Stay, Federal Law Enforcement Training
Center, Georgia, US.
I love this book! I have several students reading it at the moment, plan to use it in graduate course.21 ,
Research Assistant Professor Computer Science Dartmouth College
Dennis @Yurichev has published an impressive (and free!) book on reverse engineering22 Tanel Poder,
Oracle RDBMS.
This book is some kind of Wikipedia to beginners... Archer, Chinese Translator, IT Security Researcher.
, .
, DefCon-UA
2015, Acorn (
2014) .
.
Byungho Min (twitter/tais9).
: facebook/andydinka.
.
,
.
19 twitter.com/petennigan/status/400551705797869568
20 reddit
21 twitter.com/sergeybratus/status/505590326560833536
22 twitter.com/TanelPoder/status/524668104065159169
xxiii
I
, ++, , ,
. 23 . ,
/++ , , .
, , , .
- .
, ( )
.
,
, . ,
(
), .
. .
.
, .
.
, ( ) . -
( )
.
-
, , .
,
. ,
.
reverse engineer ,
, . .
23 , , , .
2
1. CPU 1. CPU
CPU
CPU .
:
: CPU. : , ,
. , CPU (ISA).
: CPU. .
: , : ,
, ..
CPU : CPU (GPR). 8 x86, 16
x86-64, 16 ARM. . ,
1 8 32 ( 64) .
!
?
/++, Java, Python, CPU . ,
CPU , . ,
- , , .
, 2 .
1.1. ISA
x86 , 64- , x64
ISA. x86 , 16- 8086 -
.
ARM RISC3 - ,
. ARM 4- 4 . ,
ARM.
, . , 5
c .
ISA Thumb, 2- .
Thumb. ARM , Thumb -
. , ARM Thumb .
ARM , Thumb : Thumb-2 ( ARMv7). Thumb-2
, 4 . ,
Thumb-2 ARM Thumb. . Thumb-2 -
ARM.
iPod/iPhone/iPad Thumb-2, Xcode .
64- ARM. ISA 4- , Thumb. 64-
1
2 .
3 Reduced instruction set computing
4 , , ( ) .
3
1. CPU 1. CPU
ISA, 3 ARM: ARM, Thumb ( Thumb-
2) ARM64. , , ,
. , ARM ISA.
RISC ISA 32- MIPS, PowerPC Alpha
AXP.
4
2. 2.
, :
, :
2.1: /++
int f()
{
return 123;
};
2.1. x86
GCC:
2.2: GCC/MSVC ( )
f:
mov eax, 123
ret
MSVC
. 123 EAX, -
. RET, .
EAX.
2.2. ARM
ARM?
5
2. 2.
2.3. MIPS
MIPS. ( $0 $31) ($V0, $A0, ..).
GCC :
IDA3 :
2.3.1. - MIPS
MIPS .
, ISA .
3 , Hex-Rays
6
3. HELLO, WORLD! 3. HELLO, WORLD!
Hello, world!
int main()
{
printf("hello, world\n");
return 0;
}
3.1. x86
3.1.1. MSVC
MSVC 2010:
cl 1.cpp /Fa1.asm
( /Fa )
7
3. HELLO, WORLD! 3. HELLO, WORLD!
#include <stdio.h>
int main()
{
printf($SG3830);
return 0;
}
. ,
/++ . : 57.1.1 (. 672).
_TEXT : main(). main(), ,
1 .
printf() : CALL _printf. ( )
PUSH .
, printf() main(), ( )
. , ( ESP) .
ADD ESP, 4 4 ESP. 4? 32- ,
4 . x64- 8 . ADD ESP, 4 POP , -
2 .
, , Intel C++ Compiler, ADD POP ECX
( , , Oracle RDBMS, ), ,
ECX. , POP ECX, (1
POP 3 ADD).
POP ADD Oracle RDBMS:
3.1.2. GCC
3.3: IDA
main proc near
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
mov eax, offset aHelloWorld ; "hello, world\n"
1 (4 (. 24)).
2 , ,
3 wikipedia
4 C runtime library : 68.1 (. 709)
5 GCC -S -masm=intel.
8
3. HELLO, WORLD! 3. HELLO, WORLD!
mov [esp+10h+var_10], eax
call _printf
mov eax, 0
leave
retn
main endp
, AT&T . -
UNIX-.
3.4: GCC 4.7.3
gcc S 1_1.c
:
3.5: GCC 4.7.3
.file "1_1.c"
.section .rodata
.LC0:
.string "hello, world\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, 8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call printf
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .main
.ident "GCC: (Ubuntu/Linaro 4.7.31ubuntu1) 4.7.3"
.section .note.GNUstack,"",@progbits
6 Wikipedia:
9
3. HELLO, WORLD! 3. HELLO, WORLD!
( ). . , ,
( .string, ,
). 7 :
3.6: GCC 4.7.3
.LC0:
.string "hello, world\n"
main:
pushl %ebp
movl %esp, %ebp
andl $16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call printf
movl $0, %eax
leave
ret
Intel AT&T :
.
Intel-: <> < > <->.
AT&T-: <> <-> < >.
, : Intel
(=) , AT&T
() 8 .
AT&T: (%), ($).
.
AT&T: , :
q quad (64 )
l long (32 )
w word (16 )
b byte (8 )
: , IDA. : 0FFFFFFF0h
$-16. : 16 0x10 . -0x10
0xFFFFFFF0 ( 32- ).
0 MOV, XOR. MOV
. ( , ). -
LOAD STORE - .
3.2. x86-64
64- MSVC:
3.7: MSVC 2012 x64
$SG2989 DB 'hello, world', 0AH, 00H
main PROC
sub rsp, 40
lea rcx, OFFSET FLAT:$SG2989
call printf
xor eax, eax
add rsp, 40
ret 0
main ENDP
7 , , GCC: -fno-asynchronous-unwind-tables
8 , (, memcpy(), strcpy()) -
Intel: , -.
10
3. HELLO, WORLD! 3. HELLO, WORLD!
x86-64 64- R-.
( , ), -
(fastcall: 64.3 (. 690)). ..
. Win64 4 RCX, RDX, R8, R9.
: printf() , RCX.
64-, 64- ( R-).
32 E-.
RAX/ EAX/ AX/ AL x86-64:
7 ( ) 6 5 4 3 2 1 0
RAXx64
EAX
AX
AH AL
main() int, /++, -
, 32-. main() RAX, EAX, .. 32- .
, 40 . shadow space, :
8.2.1 (. 94).
, , EDI 0x4004D4, 5 . ,
64- RDI, 7 . , GCC . , , ,
, , 4GiB.
EAX printf(). -
*NIX x86-64 EAX : with variable
arguments passes information about the number of vector registers used [Mit13].
9 Options Disassembly Number of opcode bytes
11
3. HELLO, WORLD! 3. HELLO, WORLD!
3.3. GCC -
, - const (3.1.1 (. 7)), , -
(immutable), : -
.
:
#include <stdio.h>
int f1()
{
printf ("world\n");
}
int f2()
{
printf ("hello world\n");
}
int main()
{
f1();
f2();
}
f2 proc near
, , puts(),
f2(), , . ,
, .
puts() f1(), world . puts() ,
- !
( GCC) .
3.4. ARM
ARM :
embedded- Keil Release 6/2013.
12
3. HELLO, WORLD! 3. HELLO, WORLD!
Apple Xcode 4.6.3 ( LLVM-GCC 4.210 ).
GCC 4.9 (Linaro) ( ARM64), win32 http://go.yurichev.com/
17325.
, , 32- ARM ( Thumb Thumb-2).
64- ARM, ARM64.
Keil:
armcc.exe arm c90 O0 1.c
armcc Intel. -
, ARM11 , ,
IDA.
3.11: Keil 6/2013 ( ARM) IDA
.text:00000000 main
.text:00000000 10 40 2D E9 STMFD SP!, {R4,LR}
.text:00000004 1E 0E 8F E2 ADR R0, aHelloWorld ; "hello, world"
.text:00000008 15 19 00 EB BL __2printf
.text:0000000C 00 00 A0 E3 MOV R0, #0
.text:00000010 10 80 BD E8 LDMFD SP!, {R4,PC}
, 4 . ,
ARM, Thumb.
, STMFD SP!, {R4,LR}12 , PUSH x86,
(R4 LR) . , armcc
PUSH {r4,lr}. , PUSH Thumb,
, , IDA.
, SP14 , , ,
R4 LR , SP.
, PUSH Thumb,
, . , x86 . , STMFD
PUSH ( ), , SP.
, STMFD .
ADR R0, aHelloWorld PC15 ,
hello, world. PC, ? , - 16
- . , -
PC . ADR ,
. , , .
, ( PC),
-.
BL __2printf17 printf(). :
BL (0xC) LR;
printf(), PC.
printf() , , , ,
, LR.
RISC- ARM CISC18 - x86,
19 .
10 : Apple Xcode 4.6.3 - GCC LLVM
11 , PUSH/ POP, ARM
12 STMFD13
14 stack pointer. SP/ESP/RSP x86/x64. SP ARM.
15 Program Counter. IP/EIP/RIP x86/64. PC ARM.
16 (67.1 (. 704))
17 Branch with Link
18 Complex instruction set computing
19 (5 (. 25))
13
3. HELLO, WORLD! 3. HELLO, WORLD!
, 32- ( ) 32- BL,
24- . ARM 4 (32 )
4, 2 ( ) . 26
, current_P C 32M .
MOV R0, #020 0 R0. - 0, -
R0.
LDMFD SP!, R4,PC21 , STMFD. (
) R4 PC, SP.
POP.
N.B. STMFD R4 LR, LDMFD
R4 PC.
, LR , .
, main() -
printf(). , ,
PC, , , .
main() /++, , -
CRT - .
BX LR .
DCB , ASCII-, DB x86-.
Keil Thumb:
armcc.exe thumb c90 O0 1.c
( IDA):
(16-) , , Thumb.
BL. 16- . 16-
, printf(). 16-
10 , 11 . ,
Thumb- 2 ( 16 ). , Thumb- -
. , . ,
Thumb- BL current_P C 2M .
(PUSH POP) , STMFD/ LDMFD,
SP . ADR , . MOVS 0
R0 .
Xcode 4.6.3 , -
( -O3), .
14
3. HELLO, WORLD! 3. HELLO, WORLD!
__text:000028CC 0D 70 A0 E1 MOV R7, SP
__text:000028D0 00 00 40 E3 MOVT R0, #0
__text:000028D4 00 00 8F E0 ADD R0, PC, R0
__text:000028D8 C3 05 00 EB BL _puts
__text:000028DC 00 00 A0 E3 MOV R0, #0
__text:000028E0 80 80 BD E8 LDMFD SP!, {R7,PC}
STMFD LDMFD .
MOV 0x1686 R0 , Hello world!.
R7 ( , [App10]) frame pointer, .
MOVT R0, #0 (MOVe Top) 0 16 . , MOV
ARM - 16 ,
. , ARM 32 . ,
. ( 16- 31- )
MOVT. , , MOV R0,
#0x1686 . , .
ADD R0, PC, R0 PC R0 Hello world!.
, - , .
BL puts() printf().
printf() puts(). , printf()
puts(). , , printf(),
. 23 .
? puts() 24 .
puts() stdout .
MOV R0, #0, 0 .
...
15
3. HELLO, WORLD! 3. HELLO, WORLD!
MOVW, MOVT.W BLX 0xFx.
Thumb-2 MOVW R0, #0x13D8 16- R0,
.
MOVT.W R0, #0 , MOVT , Thumb-2.
, BLX BL. ,
LR puts(), Thumb/Thumb-
2 ARM ( ). , , , ( -
ARM):
__symbolstub1:00003FEC _puts ; CODE XREF: _hello_world+E
__symbolstub1:00003FEC 44 F0 9F E5 LDR PC, =__imp__puts
, puts() .
, : puts()
, ?
- .
( DLL Windows, .so *NIX
.dylib Mac OS X). ,
puts().
(Windows PE .exe, ELF Mach-O) , (-
) , .
, ,
.
, __imp__puts 32- ,
. LDR 32- , ,
PC, .
,
, , , .
, , 32-
. , ARM,
, .
( thunk-) Thumb-.
, ( ARM), BL
thunk-, ( X ).
thunk-
Thunk- , , - .
- . , -
, .
Thunk- wrapper-. Wrap , .
:
A piece of coding which provides an address:, according to P. Z. Ingerman, who invented thunks in 1961
as a way of binding actual parameters to their formal denitions in Algol-60 procedure calls. If a procedure is
called with an expression in the place of a formal parameter, the compiler generates a thunk which computes
the expression and leaves the address of the result in some standard location.
Microsoft and IBM have both dened, in their Intel-based systems, a 16-bit environment (with
bletcherous segment registers and 64K address limits) and a 32-bit environment (with at addressing
and semi-real memory management). The two environments can both be running on the same computer
and OS (thanks to what is called, in the Microsoft world, WOW which stands for Windows On Windows). MS
and IBM have both decided that the process of getting from 16- to 32-bit and vice versa is called a thunk;
for Windows 95, there is even a tool THUNK.EXE called a thunk compiler.
16
3. HELLO, WORLD! 3. HELLO, WORLD!
3.4.5. ARM64
GCC
uint64_t main()
{
printf ("Hello!\n");
25 Frame Pointer
17
3. HELLO, WORLD! 3. HELLO, WORLD!
return 0;
}
, MOV :
3.5. MIPS
3.5.2. GCC
, .
18
3. HELLO, WORLD! 3. HELLO, WORLD!
16 ; puts(), link-:
17 jalr $25
18 addiu $4,$4,%lo($LC0) ; branch delay slot
19 ; RA:
20 lw $31,28($sp)
21 ; 0 $zero $v0:
22 move $2,$0
23 ; RA:
24 j $31
25 ; :
26 addiu $sp,$sp,32 ; branch delay slot
, $GP . RA
. puts() printf(). puts() $25 LW
(Load Word). $4 LUI (Load Upper Immediate) ADDIU
(Add Immediate Unsigned Word). LUI 16 (
upper) ADDIU 16 . ADDIU JALR ( branch delay slots?).
$4 $A0, 27 .
JALR (Jump and Link Register) $25 ( puts())
(LW) RA. ARM. : RA
( delay slot ),
( delay slot). JALR RA P C + 8.
LW ADDIU.
LW (Load Word) 19 RA ( ).
MOVE 22 $0 ($ZERO) $2 ($V0). MIPS , -
. , MIPS 0 ,
$0, , 0. : MIPS
, . , MOVE DST, SRC ADD DST, SRC, $ZERO
(DST = SRC + 0), . , MIPS -
. , MOVE. ,
CPU 28 .
J 24 RA, . ADDIU J
J ( branch delay slots?) .
IDA. :
19
3. HELLO, WORLD! 3. HELLO, WORLD!
28 .text:0000002C jr $ra
29 ; :
30 .text:00000030 addiu $sp, 0x20
15 GP .
GCC, - GCC29 . GP ,
64KiB.
, puts() $T9, T- temporaries
.
3.5.3. GCC
GCC .
, FP . 3 NOP30 -.
.
, GCC NOP- (- branch delay slots) ,
, . .
IDA:
29 , GCC, .
30 No OPeration
20
3. HELLO, WORLD! 3. HELLO, WORLD!
1 .text:00000000 main:
2 .text:00000000
3 .text:00000000 var_10 = 0x10
4 .text:00000000 var_8 = 8
5 .text:00000000 var_4 = 4
6 .text:00000000
7 ;
8 ; GP FP :
9 .text:00000000 addiu $sp, 0x20
10 .text:00000004 sw $ra, 0x20+var_4($sp)
11 .text:00000008 sw $fp, 0x20+var_8($sp)
12 ; FP ( ):
13 .text:0000000C move $fp, $sp
14 ; GP:
15 .text:00000010 la $gp, __gnu_local_gp
16 .text:00000018 sw $gp, 0x20+var_10($sp)
17 ; :
18 .text:0000001C lui $v0, (aHelloWorld >> 16) # "Hello, world!"
19 .text:00000020 addiu $a0, $v0, (aHelloWorld & 0xFFFF) # "Hello, world!"
20 ; puts() GP:
21 .text:00000024 lw $v0, (puts & 0xFFFF)($gp)
22 .text:00000028 or $at, $zero ; NOP
23 ; puts():
24 .text:0000002C move $t9, $v0
25 .text:00000030 jalr $t9
26 .text:00000034 or $at, $zero ; NOP
27 ; GP :
28 .text:00000038 lw $gp, 0x20+var_10($fp)
29 ; $2 ($V0) :
30 .text:0000003C move $v0, $zero
31 ; .
32 ; SP:
33 .text:00000040 move $sp, $fp
34 ; RA:
35 .text:00000044 lw $ra, 0x20+var_4($sp)
36 ; FP:
37 .text:00000048 lw $fp, 0x20+var_8($sp)
38 .text:0000004C addiu $sp, 0x20
39 ; RA:
40 .text:00000050 jr $ra
41 .text:00000054 or $at, $zero ; NOP
3.5.4.
. ? ,
RA GP - ( printf())
. leaf function, . : 2.3
(. 6).
3.22: GDB
root@debianmips:~# gcc hw.c O3 o hw
root@debianmips:~# gdb hw
GNU gdb (GDB) 7.0.1debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
21
3. HELLO, WORLD! 3. HELLO, WORLD!
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mipslinuxgnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/hw...(no debugging symbols found)...done.
(gdb) b main
Breakpoint 1 at 0x400654
(gdb) run
Starting program: /root/hw
3.6.
x86/ARM x64/ARM64 , 64-. ,
CPU 64-, ,
, , 32- . 64-.
3.7.
3.7.1. #1
main:
push 0xFFFFFFFF
call MessageBeep
xor eax,eax
retn
win32-?
: G.1.1 (. 985).
3.7.2. #2
22
3. HELLO, WORLD! 3. HELLO, WORLD!
main:
pushq %rbp
movq %rsp, %rbp
movl $2, %edi
call sleep
popq %rbp
ret
Linux-? AT&T- .
: G.1.1 (. 985).
23
4. 4.
. - :
push ebp
mov ebp, esp
sub esp, X
4.1.
.
: 36.3 (. 490).
24
5. 5.
1 .
+ ESP x86 RSP x64, SP ARM,
- .
PUSH POP ( x86 Thumb- ARM). PUSH -
ESP/ RSP/SP 4 32- ( 8 64-), ,
ESP/ RSP/SP, .
POP (
) 4 ( 8).
- . PUSH -, POP .
, . , .
ARM, , , , -
.
5.1. ?
, , , , ..
.
, , , . ,
: . ,
, .
Heap . Stack
[RT74] :
1 wikipedia.org/wiki/Call_stack
2 Store Multiple Empty Descending ( ARM)
3 Load Multiple Empty Descending ( ARM)
4 Store Multiple Full Ascending ( ARM)
5 Load Multiple Full Ascending ( ARM)
6 Store Multiple Empty Ascending ( ARM)
7 Load Multiple Empty Ascending ( ARM)
25
5. 5.
The user-core part of an image is divided into three logical segments. The program text segment begins
at location 0 in the virtual address space. During execution, this segment is write-protected and a single
copy of it is shared among all processes executing the same program. At the rst 8K byte boundary above
the program text segment in the virtual address space begins a nonshared, writable data segment, the size
of which may be extended by a system call. Starting at the highest address in the virtual address space is a
stack segment, which automatically grows downward as the hardwares stack pointer uctuates.
: -
, , . - ,
.
5.2. ?
5.2.1.
x86
CALL ,
CALL, ( JMP) , .
CALL PUSH address_after_call / JMP.
RET POP tmp /
JMP tmp.
, :
void f()
{
f();
};
MSVC 2008 :
c:\tmp6>cl ss.cpp /Fass.asm
Microsoft (R) 32bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
ss.cpp
c:\tmp6\ss.cpp(4) : warning C4717: 'f' : recursive on all control paths, function will cause runtime
stack overflow
, , :
?f@@YAXXZ PROC ; f
; File c:\tmp6\ss.cpp
; Line 2
push ebp
mov ebp, esp
; Line 3
call ?f@@YAXXZ ; f
; Line 4
pop ebp
ret 0
?f@@YAXXZ ENDP ; f
, (/Ox), , ,
8 :
?f@@YAXXZ PROC ; f
; File c:\tmp6\ss.cpp
; Line 2
$LL3@f:
; Line 3
jmp SHORT $LL3@f
8
26
5. 5.
?f@@YAXXZ ENDP ; f
GCC 4.4.1 , .
ARM
ARM RA, , . -
Hello, world! (3.4 (. 12)), RA LR (link register).
- LR , .
, PUSH R4-R7,LR , POP R4-R7,PC
, , LR.
, , RISC leaf
function9 . , leaf- LR ( ).
, , . , ARM
leaf- . x86,
10 . , ,
.
: 8.3.2 (. 97), 8.3.3 (. 97), 19.17 (. 326), 19.33 (. 343), 19.5.4 (. 344), 15.4
(. 205), 15.2 (. 204), 17.3 (. 225).
5.2.2.
x86 cdecl:
push arg3
push arg2
push arg1
call f
add esp, 12 ; 4*3=12
.
, f():
ESP
ESP+4 #1, IDA arg_0
ESP+8 #2, IDA arg_4
ESP+0xC #3, IDA arg_8
. (64 (. 689)). ,
, , ,
. , .
, ,
EAX. 11 . , x86 ARM -
.
, .
( printf()) (
%). -
printf("%d %d %d", 1234);
printf() 1234, , .
JMP, .
, IBM System/360.
27
5. 5.
push envp
push argv
push argc
call main
...
main() , , , , .
main() main(int argc, char *argv[]), ,
. , main(int argc), .
5.2.3.
,
. .
. -
. .
alloca()12 .
malloc(), .
free() , (4 (. 24)) ESP
.
alloca().
, , ESP , ESP
. :
#ifdef __GNUC__
#include <alloca.h> // GCC
#else
#include <malloc.h> // MSVC
#endif
#include <stdio.h>
void f()
{
char *buf=(char*)alloca (600);
#ifdef __GNUC__
snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3); // GCC
#else
_snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3); // MSVC
#endif
puts (buf);
};
MSVC
(MSVC 2010):
28
5. 5.
mov eax, 600 ; 00000258H
call __alloca_probe_16
mov esi, esp
push 3
push 2
push 1
push OFFSET $SG2672
push 600 ; 00000258H
push esi
call __snprintf
push esi
call _puts
add esp, 28 ; 0000001cH
...
GCC + Intel
GCC 4.4.1 :
GCC + AT&T
, AT&T:
29
5. 5.
movl %ebx, (%esp)
movl $3, 20(%esp)
movl $2, 16(%esp)
movl $1, 12(%esp)
movl $.LC0, 8(%esp)
movl $600, 4(%esp)
call _snprintf
movl %ebx, (%esp)
call puts
movl 4(%ebp), %ebx
leave
ret
, .
, movl $3, 20(%esp) mov DWORD PTR [esp+20], 3 Intel.
+ AT&T (%).
SEH16 ( ).
: (68.3 (. 718)).
5.2.6.
(18.2 (. 274)).
5.2.7.
, SEH- , ,
, (
ADD). , , .
(heap) .
5.3.
32- :
ESP-0xC #2, IDA var_8
ESP-8 #1, IDA var_4
ESP-4 EBP
ESP
ESP+4 #1, IDA arg_0
ESP+8 #2, IDA arg_4
ESP+0xC #3, IDA arg_8
5.4.
. ? ,
. :
#include <stdio.h>
void f1()
{
int a=1, b=2, c=3;
};
16 Structured Exception Handling : 68.3 (. 718)
30
5. 5.
void f2()
{
int a, b, c;
printf ("%d, %d, %d\n", a, b, c);
};
int main()
{
f1();
f2();
};
_c$ = 12 ; size = 4
_b$ = 8 ; size = 4
_a$ = 4 ; size = 4
_f1 PROC
push ebp
mov ebp, esp
sub esp, 12
mov DWORD PTR _a$[ebp], 1
mov DWORD PTR _b$[ebp], 2
mov DWORD PTR _c$[ebp], 3
mov esp, ebp
pop ebp
ret 0
_f1 ENDP
_c$ = 12 ; size = 4
_b$ = 8 ; size = 4
_a$ = 4 ; size = 4
_f2 PROC
push ebp
mov ebp, esp
sub esp, 12
mov eax, DWORD PTR _c$[ebp]
push eax
mov ecx, DWORD PTR _b$[ebp]
push ecx
mov edx, DWORD PTR _a$[ebp]
push edx
push OFFSET $SG2752 ; '%d, %d, %d'
call DWORD PTR __imp__printf
add esp, 16
mov esp, ebp
pop ebp
ret 0
_f2 ENDP
_main PROC
push ebp
mov ebp, esp
call _f1
call _f2
xor eax, eax
pop ebp
ret 0
_main ENDP
c:\Polygon\c>cl st.c /Fast.asm /MD
Microsoft (R) 32bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
31
5. 5.
st.c
c:\polygon\c\st.c(11) : warning C4700: uninitialized local variable 'c' used
c:\polygon\c\st.c(11) : warning C4700: uninitialized local variable 'b' used
c:\polygon\c\st.c(11) : warning C4700: uninitialized local variable 'a' used
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:st.exe
st.obj
c:\Polygon\c>st
1, 2, 3
. . f2(). ,
.
32
5. 5.
OllyDbg:
f1() a, b c 0x14F860 ..
33
5. 5.
f2():
... a, b c f2() ! ,
.
SP -
, .. ).
.
, ( ) .
, , .
? ,
( ) .
5.5.
5.5.1. #1
MSVC , . ? -
MSVC (/Ox)? GCC ?
#include <stdio.h>
int main()
{
printf ("%d, %d, %d\n");
return 0;
};
: G.1.2 (. 985).
5.5.2. #2
34
5. 5.
_main PROC
push 0
call DWORD PTR __imp___time64
push edx
push eax
push OFFSET $SG3103 ; '%d'
call DWORD PTR __imp__printf
add esp, 16
xor eax, eax
ret 0
_main ENDP
|L0.32|
DCB "%d\n",0
|L0.20|
DCB "%d\n",0
var_10 = 0x10
var_4 = 4
35
5. 5.
sw $ra, 0x20+var_4($sp)
sw $gp, 0x20+var_10($sp)
lw $t9, (time & 0xFFFF)($gp)
or $at, $zero
jalr $t9
move $a0, $zero
lw $gp, 0x20+var_10($sp)
lui $a0, ($LC0 >> 16) # "%d\n"
lw $t9, (printf & 0xFFFF)($gp)
lw $ra, 0x20+var_4($sp)
la $a0, ($LC0 & 0xFFFF) # "%d\n"
move $a1, $v0
jr $t9
addiu $sp, 0x20
: G.1.2 (. 985).
36
6. PRINTF() 6. PRINTF()
printf()
int main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
return 0;
};
6.1. x86
6.1.1. x86: 3
MSVC
...
push 3
push 2
push 1
push OFFSET $SG3830
call _printf
add esp, 16 ; 00000010H
, , , printf()
: .
, , int 32- , , 32 , 4 .
, 4 . 4 4 = 16 16 3
int.
ADD ESP, X ESP - ,
, , X 4.
, cdecl- , 32- .
. (64 (. 689)).
, , ,
:
push a1
push a2
call ...
...
push a1
37
6. PRINTF() 6. PRINTF()
call ...
...
push a1
push a2
push a3
call ...
add esp, 24
6.1: x86
.text:100113E7 push 3
.text:100113E9 call sub_100018B0 ; (3)
.text:100113EE call sub_100019D0 ;
.text:100113F3 call sub_10006A90 ;
.text:100113F8 push 1
.text:100113FA call sub_100018B0 ; (1)
.text:100113FF add esp, 8 ;
38
6. PRINTF() 6. PRINTF()
MSVC OllyDbg
OllyDbg. win32- .
MSVC 2012 /MD MSVCR*.DLL,
.
OllyDbg. ntdll.dll, F9 ().
CRT-. main().
, (MSVC main()
):
39
6. PRINTF() 6. PRINTF()
F8 ( , ) 6 , .. 6 :
? :
. 6.3: OllyDbg: ( )
3 : , OllyDbg. OllyDbg
printf()-, 3 .
, Follow in dump
, - . .
, .
, , .
40
6. PRINTF() 6. PRINTF()
F8 ( , ).
:
. 6.4: printf()
41
6. PRINTF() 6. PRINTF()
F8 , ADD ESP, 10:
ESP , ! , -
. (SP) .
, , .
GCC
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
mov eax, offset aADBDCD ; "a=%d; b=%d; c=%d"
mov [esp+10h+var_4], 3
mov [esp+10h+var_8], 2
mov [esp+10h+var_C], 1
mov [esp+10h+var_10], eax
call _printf
mov eax, 0
leave
retn
main endp
, GCC, MSVC
. GCC PUSH/ POP.
GCC GDB
GDB1 Linux.
-g .
$ gcc 1.c g o 1
1 GNU debugger
42
6. PRINTF() 6. PRINTF()
$ gdb 1
GNU gdb (GDB) 7.6.1ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686linuxgnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dennis/polygon/1...done.
6.2: printf()
(gdb) b printf
Breakpoint 1 at 0x80482f0
. printf(), GDB .
(gdb) run
Starting program: /home/dennis/polygon/1
10 . .
(gdb) x/10w $esp
0xbffff11c: 0x0804844a 0x080484f0 0x00000001 0x00000002
0xbffff12c: 0x00000003 0x08048460 0x00000000 0x00000000
0xbffff13c: 0xb7e29905 0x00000001
RA (0x0804844a). , :
(gdb) x/5i 0x0804844a
0x804844a <main+45>: mov $0x0,%eax
0x804844f <main+50>: leave
0x8048450 <main+51>: ret
0x8048451: xchg %ax,%ax
0x8048453: xchg %ax,%ax
XCHG , NOP.
(0x080484f0) :
(gdb) x/s 0x080484f0
0x80484f0: "a=%d; b=%d; c=%d"
3 (1, 2, 3) printf(). ,
, , .. .
nish. . -
printf().
(gdb) finish
Run till exit from #0 __printf (format=0x80484f0 "a=%d; b=%d; c=%d") at printf.c:29
main () at 1.c:6
6 return 0;
Value returned is $2 = 13
43
6. PRINTF() 6. PRINTF()
. , -
.
(gdb) disas
Dump of assembler code for function main:
0x0804841d <+0>: push %ebp
0x0804841e <+1>: mov %esp,%ebp
0x08048420 <+3>: and $0xfffffff0,%esp
0x08048423 <+6>: sub $0x10,%esp
0x08048426 <+9>: movl $0x3,0xc(%esp)
0x0804842e <+17>: movl $0x2,0x8(%esp)
0x08048436 <+25>: movl $0x1,0x4(%esp)
0x0804843e <+33>: movl $0x80484f0,(%esp)
0x08048445 <+40>: call 0x80482f0 <printf@plt>
=> 0x0804844a <+45>: mov $0x0,%eax
0x0804844f <+50>: leave
0x08048450 <+51>: ret
End of assembler dump.
GDB AT&T. -
Intel:
(gdb) set disassemblyflavor intel
(gdb) disas
Dump of assembler code for function main:
0x0804841d <+0>: push ebp
0x0804841e <+1>: mov ebp,esp
0x08048420 <+3>: and esp,0xfffffff0
0x08048423 <+6>: sub esp,0x10
0x08048426 <+9>: mov DWORD PTR [esp+0xc],0x3
0x0804842e <+17>: mov DWORD PTR [esp+0x8],0x2
0x08048436 <+25>: mov DWORD PTR [esp+0x4],0x1
0x0804843e <+33>: mov DWORD PTR [esp],0x80484f0
0x08048445 <+40>: call 0x80482f0 <printf@plt>
=> 0x0804844a <+45>: mov eax,0x0
0x0804844f <+50>: leave
0x08048450 <+51>: ret
End of assembler dump.
. GDB , , .
(gdb) step
7 };
44
6. PRINTF() 6. PRINTF()
6.1.2. x64: 8
, , ,
9 ( printf() 8 int):
#include <stdio.h>
int main()
{
printf("a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n", 1, 2, 3, 4, 5, 6, 7, 8);
return 0;
};
MSVC
main PROC
sub rsp, 88
; 0
xor eax, eax
add rsp, 88
ret 0
main ENDP
_TEXT ENDS
END
, int 8 , 4? ,
: 64-, 8 . :
. ,
. 32- : 4 .
GCC
main:
sub rsp, 40
mov r9d, 5
45
6. PRINTF() 6. PRINTF()
mov r8d, 4
mov ecx, 3
mov edx, 2
mov esi, 1
mov edi, OFFSET FLAT:.LC0
xor eax, eax ;
mov DWORD PTR [rsp+16], 8
mov DWORD PTR [rsp+8], 7
mov DWORD PTR [rsp], 6
call printf
; 0
GCC + GDB
GDB.
$ gcc g 2.c o 2
$ gdb 2
GNU gdb (GDB) 7.6.1ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64linuxgnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dennis/polygon/2...done.
6.5: printf(),
(gdb) b printf
Breakpoint 1 at 0x400410
(gdb) run
Starting program: /home/dennis/polygon/2
Breakpoint 1, __printf (format=0x400628 "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n") at printf.
c:29
29 printf.c: No such file or directory.
46
6. PRINTF() 6. PRINTF()
6.6:
(gdb) x/s $rdi
0x400628: "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n"
, , RA. 3 : 6, 7, 8. , 8
32- : 0x00007fff00000008. ,
int, 32-. .
GDB main(), , printf():
(gdb) set disassemblyflavor intel
(gdb) disas 0x0000000000400576
Dump of assembler code for function main:
0x000000000040052d <+0>: push rbp
0x000000000040052e <+1>: mov rbp,rsp
0x0000000000400531 <+4>: sub rsp,0x20
0x0000000000400535 <+8>: mov DWORD PTR [rsp+0x10],0x8
0x000000000040053d <+16>: mov DWORD PTR [rsp+0x8],0x7
0x0000000000400545 <+24>: mov DWORD PTR [rsp],0x6
0x000000000040054c <+31>: mov r9d,0x5
0x0000000000400552 <+37>: mov r8d,0x4
0x0000000000400558 <+43>: mov ecx,0x3
0x000000000040055d <+48>: mov edx,0x2
0x0000000000400562 <+53>: mov esi,0x1
0x0000000000400567 <+58>: mov edi,0x400628
0x000000000040056c <+63>: mov eax,0x0
0x0000000000400571 <+68>: call 0x400410 <printf@plt>
0x0000000000400576 <+73>: mov eax,0x0
0x000000000040057b <+78>: leave
0x000000000040057c <+79>: ret
End of assembler dump.
47
6. PRINTF() 6. PRINTF()
rip 0x40057b 0x40057b <main+78>
...
6.2. ARM
6.2.1. ARM: 3
ARM : 4 R0-R3;
. , fastcall (64.3 (. 690)) win64 (64.5.1
(. 691)).
32- ARM
, 4 R0-R3, : - printf()
R0, 1 R1, 2 R2 3 R3.
0x18 0 R0 return 0.
.
Keil 6/2013 .
ARM.
, return 0:
#include <stdio.h>
void main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
};
48
6. PRINTF() 6. PRINTF()
:
(-O3) ARM, B
BL. , ,
, (, R0 LR). B
, LR, JMP x86.
? . : 1) ,
SP; 2) printf() , . printf(),
, , LR. LR ,
! , printf() .
LR, LR. LR, ,
printf(), , !
.
, .
: 13.1.1 (. 149).
ARM64
6.2.2. ARM: 8
9- : 6.1.2 (. 45).
#include <stdio.h>
int main()
{
49
6. PRINTF() 6. PRINTF()
printf("a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n", 1, 2, 3, 4, 5, 6, 7, 8);
return 0;
};
.text:00000028 main
.text:00000028
.text:00000028 var_18 = 0x18
.text:00000028 var_14 = 0x14
.text:00000028 var_4 = 4
.text:00000028
.text:00000028 04 E0 2D E5 STR LR, [SP,#var_4]!
.text:0000002C 14 D0 4D E2 SUB SP, SP, #0x14
.text:00000030 08 30 A0 E3 MOV R3, #8
.text:00000034 07 20 A0 E3 MOV R2, #7
.text:00000038 06 10 A0 E3 MOV R1, #6
.text:0000003C 05 00 A0 E3 MOV R0, #5
.text:00000040 04 C0 8D E2 ADD R12, SP, #0x18+var_14
.text:00000044 0F 00 8C E8 STMIA R12, {R0R3}
.text:00000048 04 00 A0 E3 MOV R0, #4
.text:0000004C 00 00 8D E5 STR R0, [SP,#0x18+var_18]
.text:00000050 03 30 A0 E3 MOV R3, #3
.text:00000054 02 20 A0 E3 MOV R2, #2
.text:00000058 01 10 A0 E3 MOV R1, #1
.text:0000005C 6E 0F 8F E2 ADR R0, aADBDCDDDEDFDGD ; "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%"...
.text:00000060 BC 18 00 EB BL __2printf
.text:00000064 14 D0 8D E2 ADD SP, SP, #0x14
.text:00000068 04 F0 9D E4 LDR PC, [SP+4+var_4],#4
:
:
STR LR, [SP,#var_4]! LR, -
printf(). pre-index. , SP
4, SP LR. x86 -
PUSH. : 28.2 (. 464).
SUB SP, SP, #0x14 SP, , ,
0x14 (20) . , 5 32-
printf(). 4 , 5 4 = 20. 4 32-
.
5, 6, 7 8 : R0, R1, R2 R3 . ADD
R12, SP, #0x18+var_14 R12 , 4 .
var_14 , -0x14. IDA, ,
. var_?, IDA, R12
SP+4. STMIA R12, R0-R3 R0-R3
, R12. STMIA Store Multiple Increment After. Increment
After , R12 4 .
4 : 4 R0, STR R0, [SP,#0x18+var_18]
. var_18 -0x18, 0, R0 (4) , SP.
1, 2 3 :
(a, b, c) (1, 2, 3 ) R1, R2 R3
printf(), 5 , :
printf().
:
ADD SP, SP, #0x14 SP , , -
. , , ,
.
LDR PC, [SP+4+var_4],#4 PC LR ,
. , PC ,
SP (4 + var_4 = 4 + (4) = 0, LDR PC, [SP],#4),
50
6. PRINTF() 6. PRINTF()
SP 4. post-index2 . IDA ?
, var_4
LR. - POP PC x863 .
.text:0000001C printf_main2
.text:0000001C
.text:0000001C var_18 = 0x18
.text:0000001C var_14 = 0x14
.text:0000001C var_8 = 8
.text:0000001C
.text:0000001C 00 B5 PUSH {LR}
.text:0000001E 08 23 MOVS R3, #8
.text:00000020 85 B0 SUB SP, SP, #0x14
.text:00000022 04 93 STR R3, [SP,#0x18+var_8]
.text:00000024 07 22 MOVS R2, #7
.text:00000026 06 21 MOVS R1, #6
.text:00000028 05 20 MOVS R0, #5
.text:0000002A 01 AB ADD R3, SP, #0x18+var_14
.text:0000002C 07 C3 STMIA R3!, {R0R2}
.text:0000002E 04 20 MOVS R0, #4
.text:00000030 00 90 STR R0, [SP,#0x18+var_18]
.text:00000032 03 23 MOVS R3, #3
.text:00000034 02 22 MOVS R2, #2
.text:00000036 01 21 MOVS R1, #1
.text:00000038 A0 A0 ADR R0, aADBDCDDDEDFDGD ; "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%"...
.text:0000003A 06 F0 D9 F8 BL __2printf
.text:0000003E
.text:0000003E loc_3E ; CODE XREF: example13_f+16
.text:0000003E 05 B0 ADD SP, SP, #0x14
.text:00000040 00 BD POP {PC}
, Thumb
: 8 , 5, 6, 7 4 .
__text:0000290C _printf_main2
__text:0000290C
__text:0000290C var_1C = 0x1C
__text:0000290C var_C = 0xC
__text:0000290C
__text:0000290C 80 40 2D E9 STMFD SP!, {R7,LR}
__text:00002910 0D 70 A0 E1 MOV R7, SP
__text:00002914 14 D0 4D E2 SUB SP, SP, #0x14
__text:00002918 70 05 01 E3 MOV R0, #0x1570
__text:0000291C 07 C0 A0 E3 MOV R12, #7
__text:00002920 00 00 40 E3 MOVT R0, #0
__text:00002924 04 20 A0 E3 MOV R2, #4
__text:00002928 00 00 8F E0 ADD R0, PC, R0
__text:0000292C 06 30 A0 E3 MOV R3, #6
__text:00002930 05 10 A0 E3 MOV R1, #5
__text:00002934 00 20 8D E5 STR R2, [SP,#0x1C+var_1C]
__text:00002938 0A 10 8D E9 STMFA SP, {R1,R3,R12}
__text:0000293C 08 90 A0 E3 MOV R9, #8
__text:00002940 01 10 A0 E3 MOV R1, #1
__text:00002944 02 20 A0 E3 MOV R2, #2
__text:00002948 03 30 A0 E3 MOV R3, #3
__text:0000294C 10 90 8D E5 STR R9, [SP,#0x1C+var_C]
__text:00002950 A4 05 00 EB BL _printf
__text:00002954 07 D0 A0 E1 MOV SP, R7
__text:00002958 80 80 BD E8 LDMFD SP!, {R7,PC}
2 : 28.2 (. 464).
3 x86 IP/EIP/RIP POP, , .
51
6. PRINTF() 6. PRINTF()
, , , STMFA (Store Multiple Full Ascending)
STMIB (Store Multiple Increment Before). SP
, .
, . , R0
, 0x2918, 0x2920 0x2928, .
, ,
.
. , MOVT R0, #0 ADD R0, PC, R0 ,
R0. MOVT R0, #0 MOV R2, #4 -
, . ,
, .
__text:00002BA0 _printf_main2
__text:00002BA0
__text:00002BA0 var_1C = 0x1C
__text:00002BA0 var_18 = 0x18
__text:00002BA0 var_C = 0xC
__text:00002BA0
__text:00002BA0 80 B5 PUSH {R7,LR}
__text:00002BA2 6F 46 MOV R7, SP
__text:00002BA4 85 B0 SUB SP, SP, #0x14
__text:00002BA6 41 F2 D8 20 MOVW R0, #0x12D8
__text:00002BAA 4F F0 07 0C MOV.W R12, #7
__text:00002BAE C0 F2 00 00 MOVT.W R0, #0
__text:00002BB2 04 22 MOVS R2, #4
__text:00002BB4 78 44 ADD R0, PC ; char *
__text:00002BB6 06 23 MOVS R3, #6
__text:00002BB8 05 21 MOVS R1, #5
__text:00002BBA 0D F1 04 0E ADD.W LR, SP, #0x1C+var_18
__text:00002BBE 00 92 STR R2, [SP,#0x1C+var_1C]
__text:00002BC0 4F F0 08 09 MOV.W R9, #8
__text:00002BC4 8E E8 0A 10 STMIA.W LR, {R1,R3,R12}
__text:00002BC8 01 21 MOVS R1, #1
__text:00002BCA 02 22 MOVS R2, #2
__text:00002BCC 03 23 MOVS R3, #3
__text:00002BCE CD F8 10 90 STR.W R9, [SP,#0x1C+var_C]
__text:00002BD2 01 F0 0A EA BLX _printf
__text:00002BD6 05 B0 ADD SP, SP, #0x14
__text:00002BD8 80 BD POP {R7,PC}
, , , Thumb-.
ARM64
52
6. PRINTF() 6. PRINTF()
mov w3, 3
mov w4, 4
mov w5, 5
mov w6, 6
mov w7, 7
bl printf
sub sp, x29, #16
; FP LR
ldp x29, x30, [sp,16]
add sp, sp, 32
ret
6.3. MIPS
6.3.1. 3
GCC 4.4.5
; :
lw $31,28($sp)
; 0:
move $2,$0
;
j $31
addiu $sp,$sp,32 ; branch delay slot
53
6. PRINTF() 6. PRINTF()
.text:00000000
; :
.text:00000000 lui $gp, (__gnu_local_gp >> 16)
.text:00000004 addiu $sp, 0x20
.text:00000008 la $gp, (__gnu_local_gp & 0xFFFF)
.text:0000000C sw $ra, 0x20+var_4($sp)
.text:00000010 sw $gp, 0x20+var_10($sp)
; printf():
.text:00000014 lw $t9, (printf & 0xFFFF)($gp)
; printf():
.text:00000018 la $a0, $LC0 # "a=%d; b=%d; c=%d"
; printf():
.text:00000020 li $a1, 1
; printf():
.text:00000024 li $a2, 2
; printf():
.text:00000028 jalr $t9
; printf() (branch delay slot):
.text:0000002C li $a3, 3
; :
.text:00000030 lw $ra, 0x20+var_4($sp)
; 0:
.text:00000034 move $v0, $zero
;
.text:00000038 jr $ra
.text:0000003C addiu $sp, 0x20 ; branch delay slot
GCC 4.4.5
GCC :
; :
lw $28,16($fp)
; 0:
move $2,$0
54
6. PRINTF() 6. PRINTF()
move $sp,$fp
lw $31,28($sp)
lw $fp,24($sp)
addiu $sp,$sp,32
;
j $31
nop
6.3.2. 8
9- : 6.1.2 (. 45).
#include <stdio.h>
int main()
{
printf("a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n", 1, 2, 3, 4, 5, 6, 7, 8);
return 0;
};
55
6. PRINTF() 6. PRINTF()
GCC 4.4.5
4 $A0 $A3, .
O32 ( MIPS). ( N32)
.
SW Store Word ( ). MIPS ,
(LI/SW).
; :
lw $31,52($sp)
; 0:
move $2,$0
;
j $31
addiu $sp,$sp,56 ; branch delay slot
56
6. PRINTF() 6. PRINTF()
.text:0000000C sw $ra, 0x38+var_4($sp)
.text:00000010 sw $gp, 0x38+var_10($sp)
; 5- :
.text:00000014 li $v0, 4
.text:00000018 sw $v0, 0x38+var_28($sp)
; 6- :
.text:0000001C li $v0, 5
.text:00000020 sw $v0, 0x38+var_24($sp)
; 7- :
.text:00000024 li $v0, 6
.text:00000028 sw $v0, 0x38+var_20($sp)
; 8- :
.text:0000002C li $v0, 7
.text:00000030 lw $t9, (printf & 0xFFFF)($gp)
.text:00000034 sw $v0, 0x38+var_1C($sp)
; 1- $a0:
.text:00000038 lui $a0, ($LC0 >> 16) # "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g
=%"...
; 9- :
.text:0000003C li $v0, 8
.text:00000040 sw $v0, 0x38+var_18($sp)
; 1- $a1:
.text:00000044 la $a0, ($LC0 & 0xFFFF) # "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g
=%"...
; 2- $a1:
.text:00000048 li $a1, 1
; 3- $a2:
.text:0000004C li $a2, 2
; printf():
.text:00000050 jalr $t9
; 4- $a3 (branch delay slot):
.text:00000054 li $a3, 3
; :
.text:00000058 lw $ra, 0x38+var_4($sp)
; 0:
.text:0000005C move $v0, $zero
;
.text:00000060 jr $ra
.text:00000064 addiu $sp, 0x38 ; branch delay slot
GCC 4.4.5
GCC :
57
6. PRINTF() 6. PRINTF()
sw $3,28($sp)
; 9- :
li $3,8 # 0x8
sw $3,32($sp)
; 1- $a0:
move $4,$2
; 2- $a1:
li $5,1 # 0x1
; 3- $a2:
li $6,2 # 0x2
; 4- $a3:
li $7,3 # 0x3
; printf():
lw $2,%call16(printf)($28)
nop
move $25,$2
jalr $25
nop
; :
lw $28,40($fp)
; 0:
move $2,$0
move $sp,$fp
lw $31,52($sp)
lw $fp,48($sp)
addiu $sp,$sp,56
;
j $31
nop
58
6. PRINTF() 6. PRINTF()
.text:00000050 li $a1, 1
; 3- $a2:
.text:00000054 li $a2, 2
; 4- $a3:
.text:00000058 li $a3, 3
; printf():
.text:0000005C lw $v0, (printf & 0xFFFF)($gp)
.text:00000060 or $at, $zero
.text:00000064 move $t9, $v0
.text:00000068 jalr $t9
.text:0000006C or $at, $zero ; NOP
; :
.text:00000070 lw $gp, 0x38+var_10($fp)
; 0:
.text:00000074 move $v0, $zero
.text:00000078 move $sp, $fp
.text:0000007C lw $ra, 0x38+var_4($sp)
.text:00000080 lw $fp, 0x38+var_8($sp)
.text:00000084 addiu $sp, 0x38
;
.text:00000088 jr $ra
.text:0000008C or $at, $zero ; NOP
6.4.
:
6.20: x86
...
PUSH
PUSH
PUSH
CALL
; ( )
6.23: ARM
MOV R0,
MOV R1,
MOV R2,
MOV R3, 4-
; 5-, 6- , .., ( )
BL
; ( )
59
6. PRINTF() 6. PRINTF()
6.24: ARM64
MOV X0,
MOV X1,
MOV X2,
MOV X3, 4-
MOV X4, 5-
MOV X5, 6-
MOV X6, 7-
MOV X7, 8-
; 9-, 10- , .., ( )
BL CALL
; ( )
6.5.
, x86, x64, fastcall, ARM MIPS
, , , , .
, , -
.
$A0$A3 MIPS ( O32). -
( , $ZERO)
.
CPU .
,
, , . .
60
7. SCANF() 7. SCANF()
scanf()
scanf().
7.1.
#include <stdio.h>
int main()
{
int x;
printf ("Enter X:\n");
return 0;
};
scanf() , - .
int.
7.1.1.
. ,
, , .
, (callee) - ,
. , , -callee
, callee - .
/++ - .
x86 32- (.. 4 ), x86-64 64- (
8 ). , , x86-64
2 , -.
(void*); ,
memcpy(), , 2 void*,
, . ,
.
, (
(10 (. 104)) ). scanf() . , ,
, .
/++ . , ,
.
61
7. SCANF() 7. SCANF()
7.1.2. x86
MSVC
, MSVC 2010:
CONST SEGMENT
$SG3831 DB 'Enter X:', 0aH, 00H
$SG3832 DB '%d', 00H
$SG3833 DB 'You entered %d...', 0aH, 00H
CONST ENDS
PUBLIC _main
EXTRN _scanf:PROC
EXTRN _printf:PROC
; Function compile flags: /Odtp
_TEXT SEGMENT
_x$ = 4 ; size = 4
_main PROC
push ebp
mov ebp, esp
push ecx
push OFFSET $SG3831 ; 'Enter X:'
call _printf
add esp, 4
lea eax, DWORD PTR _x$[ebp]
push eax
push OFFSET $SG3832 ; '%d'
call _scanf
add esp, 8
mov ecx, DWORD PTR _x$[ebp]
push ecx
push OFFSET $SG3833 ; 'You entered %d...'
call _printf
add esp, 8
; 0
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
x .
/++ . ,
. , , x86 .
PUSH ECX ECX. (
POP ECX ).
4 x .
x _x$ ( -4) EBP
.
EBP EBP+
, .
ESP, , .
, EBP ESP .
32- :
62
7. SCANF() 7. SCANF()
EBP-8 #2, IDA var_8
EBP-4 #1, IDA var_4
EBP EBP
EBP+4
EBP+8 #1, IDA arg_0
EBP+0xC #2, IDA arg_4
EBP+0x10 #3, IDA arg_8
scanf() .
, %d x.
x EAX lea eax, DWORD PTR _x$[ebp].
LEA load effective address, - (A.6.2 (. 965)).
, LEA EAX EBP
_x$.
lea eax, [ebp-4].
, EBP 4 EAX. EAX
scanf().
printf(). : You entered %d...\n.
: mov ecx, [ebp-4]. ECX x, .
ECX printf().
63
7. SCANF() 7. SCANF()
7.1.3. MSVC + OllyDbg
OllyDbg. , F8 ( , ) ,
, ntdll.dll. , main().
(PUSH EBP), F2 (set a breakpoint), F9 (Run)
main().
, x:
. 7.1: OllyDbg:
. 7.2:
64
7. SCANF() 7. SCANF()
scanf() :
scanf() 1 EAX, , .
0x7B (123).
65
7. SCANF() 7. SCANF()
ECX printf() :
GCC
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 20h
mov [esp+20h+var_20], offset aEnterX ; "Enter X:"
call _puts
mov eax, offset aD ; "%d"
lea edx, [esp+20h+var_4]
mov [esp+20h+var_1C], edx
mov [esp+20h+var_20], eax
call ___isoc99_scanf
mov edx, [esp+20h+var_4]
mov eax, offset aYouEnteredD___ ; "You entered %d...\n"
mov [esp+20h+var_1C], edx
mov [esp+20h+var_20], eax
call _printf
mov eax, 0
leave
retn
main endp
, , /++-
. /++ ,
, .
66
7. SCANF() 7. SCANF()
7.1.4. x64
, .
MSVC
_TEXT SEGMENT
x$ = 32
main PROC
$LN3:
sub rsp, 56
lea rcx, OFFSET FLAT:$SG1289 ; 'Enter X:'
call printf
lea rdx, QWORD PTR x$[rsp]
lea rcx, OFFSET FLAT:$SG1291 ; '%d'
call scanf
mov edx, DWORD PTR x$[rsp]
lea rcx, OFFSET FLAT:$SG1292 ; 'You entered %d...'
call printf
; 0
xor eax, eax
add rsp, 56
ret 0
main ENDP
_TEXT ENDS
GCC
main:
sub rsp, 24
mov edi, OFFSET FLAT:.LC0 ; "Enter X:"
call puts
lea rsi, [rsp+12]
mov edi, OFFSET FLAT:.LC1 ; "%d"
xor eax, eax
call __isoc99_scanf
mov esi, DWORD PTR [rsp+12]
mov edi, OFFSET FLAT:.LC2 ; "You entered %d...\n"
xor eax, eax
call printf
; 0
xor eax, eax
add rsp, 24
ret
67
7. SCANF() 7. SCANF()
7.1.5. ARM
.text:00000042 scanf_main
.text:00000042
.text:00000042 var_8 = 8
.text:00000042
.text:00000042 08 B5 PUSH {R3,LR}
.text:00000044 A9 A0 ADR R0, aEnterX ; "Enter X:\n"
.text:00000046 06 F0 D3 F8 BL __2printf
.text:0000004A 69 46 MOV R1, SP
.text:0000004C AA A0 ADR R0, aD ; "%d"
.text:0000004E 06 F0 CD F8 BL __0scanf
.text:00000052 00 99 LDR R1, [SP,#8+var_8]
.text:00000054 A9 A0 ADR R0, aYouEnteredD___ ; "You entered %d...\n"
.text:00000056 06 F0 CB F8 BL __2printf
.text:0000005A 00 20 MOVS R0, #0
.text:0000005C 08 BD POP {R3,PC}
ARM64
68
7. SCANF() 7. SCANF()
38 ret
32 , . ,
? x ( 22). 28?
-, , .
scanf(), , , .
32- int. 27 printf().
7.1.6. MIPS
x , $sp + 24.
scanf(), LW (Load Word
) printf().
; printf():
lw $28,16($sp)
; printf(),
; $sp+24:
lw $5,24($sp)
lw $25,%call16(printf)($28)
lui $4,%hi($LC2)
jalr $25
addiu $4,$4,%lo($LC2) ; branch delay slot
; :
lw $31,36($sp)
; 0:
move $2,$0
; :
j $31
addiu $sp,$sp,40 ; branch delay slot
IDA :
69
7. SCANF() 7. SCANF()
.text:00000000
; :
.text:00000000 lui $gp, (__gnu_local_gp >> 16)
.text:00000004 addiu $sp, 0x28
.text:00000008 la $gp, (__gnu_local_gp & 0xFFFF)
.text:0000000C sw $ra, 0x28+var_4($sp)
.text:00000010 sw $gp, 0x28+var_18($sp)
; puts():
.text:00000014 lw $t9, (puts & 0xFFFF)($gp)
.text:00000018 lui $a0, ($LC0 >> 16) # "Enter X:"
.text:0000001C jalr $t9
.text:00000020 la $a0, ($LC0 & 0xFFFF) # "Enter X:" ; branch delay slot
; scanf():
.text:00000024 lw $gp, 0x28+var_18($sp)
.text:00000028 lui $a0, ($LC1 >> 16) # "%d"
.text:0000002C lw $t9, (__isoc99_scanf & 0xFFFF)($gp)
; scanf(), $a1=$sp+24:
.text:00000030 addiu $a1, $sp, 0x28+var_10
.text:00000034 jalr $t9 ; branch delay slot
.text:00000038 la $a0, ($LC1 & 0xFFFF) # "%d"
; printf():
.text:0000003C lw $gp, 0x28+var_18($sp)
; printf(),
; $sp+24:
.text:00000040 lw $a1, 0x28+var_10($sp)
.text:00000044 lw $t9, (printf & 0xFFFF)($gp)
.text:00000048 lui $a0, ($LC2 >> 16) # "You entered %d...\n"
.text:0000004C jalr $t9
.text:00000050 la $a0, ($LC2 & 0xFFFF) # "You entered %d...\n" ; branch delay
slot
; :
.text:00000054 lw $ra, 0x28+var_4($sp)
; 0:
.text:00000058 move $v0, $zero
; :
.text:0000005C jr $ra
.text:00000060 addiu $sp, 0x28 ; branch delay slot
7.2.
x , ?
, . -,
.
#include <stdio.h>
// x
int x;
int main()
{
printf ("Enter X:\n");
return 0;
};
_DATA SEGMENT
COMM _x:DWORD
$SG2456 DB 'Enter X:', 0aH, 00H
70
7. SCANF() 7. SCANF()
$SG2457 DB '%d', 00H
$SG2458 DB 'You entered %d...', 0aH, 00H
_DATA ENDS
PUBLIC _main
EXTRN _scanf:PROC
EXTRN _printf:PROC
; Function compile flags: /Odtp
_TEXT SEGMENT
_main PROC
push ebp
mov ebp, esp
push OFFSET $SG2456
call _printf
add esp, 4
push OFFSET _x
push OFFSET $SG2457
call _scanf
add esp, 8
mov eax, DWORD PTR _x
push eax
push OFFSET $SG2458
call _printf
add esp, 8
xor eax, eax
pop ebp
ret 0
_main ENDP
_TEXT ENDS
. x _DATA. .
, . -
( ,
?), , - , ,
1 .
:
int x=10; //
:
_DATA SEGMENT
_x DD 0aH
...
0xA DD (dword = 32 ).
.exe- IDA, , x _DATA,
.
IDA.exe , x , :
.data:0040FA80 _x dd ? ; DATA XREF: _main+10
.data:0040FA80 ; _main+22
.data:0040FA84 dword_40FA84 dd ? ; DATA XREF: _memset+1E
.data:0040FA84 ; unknown_libname_1+28
.data:0040FA88 dword_40FA88 dd ? ; DATA XREF: ___sbh_find_block+5
.data:0040FA88 ; ___sbh_free_block+2BC
.data:0040FA8C ; LPVOID lpMem
.data:0040FA8C lpMem dd ? ; DATA XREF: ___sbh_find_block+B
.data:0040FA8C ; ___sbh_free_block+2CA
.data:0040FA90 dword_40FA90 dd ? ; DATA XREF: _V6_HeapAlloc+13
.data:0040FA90 ; __calloc_impl+72
.data:0040FA94 dword_40FA94 dd ? ; DATA XREF: ___sbh_free_block+2FE
_x ?, . ,
.exe , [ISO07, 6.7.8p10].
.exe . .
, .
1 VM
71
7. SCANF() 7. SCANF()
7.2.2. MSVC: x86 + OllyDbg
. , PUSH ( x)
, , Follow in dump.
.
123, 0x7B.
7B? , 00 00 00 7B.
endianness, x86 little-endian. , , -
. : 31 (. 473).
32- EAX printf().
x 0x00C53394.
72
7. SCANF() 7. SCANF()
OllyDbg (Alt-M) , PE- .data
:
. 7.6: OllyDbg:
Linux . , x ,
_bss. ELF :
; Segment type: Uninitialized
; Segment permissions: Read/Write
- , , 10,
_data, :
; Segment type: Pure data
; Segment permissions: Read/Write
_TEXT SEGMENT
main PROC
$LN3:
sub rsp, 40
73
7. SCANF() 7. SCANF()
lea rdx, OFFSET FLAT:x
lea rcx, OFFSET FLAT:$SG2925 ; '%d'
call scanf
mov edx, DWORD PTR x
lea rcx, OFFSET FLAT:$SG2926 ; 'You entered %d...'
call printf
; 0
xor eax, eax
add rsp, 40
ret 0
main ENDP
_TEXT ENDS
x86. scanf() x
LEA, printf() MOV . DWORD PTR
( ) ,
32-, MOV .
, x , , -, ,
(.data). , (.text), x ?
, , . , . -
, , .text.
( , embedded-,
), . , -
, . ,
, , , , .
74
7. SCANF() 7. SCANF()
x (off_2C)
. , x -
, . LDR Thumb-
1020 .
ARM- 4095 . , x
, , 2
- , !
: const, Keil .constdata.
, .
7.2.6. ARM64
x , ADRP/ADD ( 21 25).
7.2.7. MIPS
x . IDA. IDA
x ELF- .sbss ( Global Pointer? 3.5.1 (. 18)),
.
2 linker
75
7. SCANF() 7. SCANF()
.text:004006C0 main:
.text:004006C0
.text:004006C0 var_10 = 0x10
.text:004006C0 var_4 = 4
.text:004006C0
; :
.text:004006C0 lui $gp, 0x42
.text:004006C4 addiu $sp, 0x20
.text:004006C8 li $gp, 0x418940
.text:004006CC sw $ra, 0x20+var_4($sp)
.text:004006D0 sw $gp, 0x20+var_10($sp)
; puts():
.text:004006D4 la $t9, puts
.text:004006D8 lui $a0, 0x40
.text:004006DC jalr $t9 ; puts
.text:004006E0 la $a0, aEnterX # "Enter X:" ; branch delay slot
; scanf():
.text:004006E4 lw $gp, 0x20+var_10($sp)
.text:004006E8 lui $a0, 0x40
.text:004006EC la $t9, __isoc99_scanf
; x:
.text:004006F0 la $a1, x
.text:004006F4 jalr $t9 ; __isoc99_scanf
.text:004006F8 la $a0, aD # "%d" ; branch delay slot
; printf():
.text:004006FC lw $gp, 0x20+var_10($sp)
.text:00400700 lui $a0, 0x40
; x:
.text:00400704 la $v0, x
.text:00400708 la $t9, printf
; "x" printf() $a1:
.text:0040070C lw $a1, (x 0x41099C)($v0)
.text:00400710 jalr $t9 ; printf
.text:00400714 la $a0, aYouEnteredD___ # "You entered %d...\n" ; branch delay
slot
; :
.text:00400718 lw $ra, 0x20+var_4($sp)
.text:0040071C move $v0, $zero
.text:00400720 jr $ra
.text:00400724 addiu $sp, 0x20 ; branch delay slot
...
IDA , objdump -
:
7.9: GCC 4.4.5 (objdump)
1 004006c0 <main>:
2 ; :
3 4006c0: 3c1c0042 lui gp,0x42
4 4006c4: 27bdffe0 addiu sp,sp,32
5 4006c8: 279c8940 addiu gp,gp,30400
6 4006cc: afbf001c sw ra,28(sp)
7 4006d0: afbc0010 sw gp,16(sp)
8 ; puts():
9 4006d4: 8f998034 lw t9,32716(gp)
10 4006d8: 3c040040 lui a0,0x40
11 4006dc: 0320f809 jalr t9
12 4006e0: 248408f0 addiu a0,a0,2288 ; branch delay slot
13 ; scanf():
14 4006e4: 8fbc0010 lw gp,16(sp)
15 4006e8: 3c040040 lui a0,0x40
16 4006ec: 8f998038 lw t9,32712(gp)
17 ; x:
76
7. SCANF() 7. SCANF()
18 4006f0: 8f858044 lw a1,32700(gp)
19 4006f4: 0320f809 jalr t9
20 4006f8: 248408fc addiu a0,a0,2300 ; branch delay slot
21 ; printf():
22 4006fc: 8fbc0010 lw gp,16(sp)
23 400700: 3c040040 lui a0,0x40
24 ; x:
25 400704: 8f828044 lw v0,32700(gp)
26 400708: 8f99803c lw t9,32708(gp)
27 ; "x" printf() $a1:
28 40070c: 8c450000 lw a1,0(v0)
29 400710: 0320f809 jalr t9
30 400714: 24840900 addiu a0,a0,2304 ; branch delay slot
31 ; :
32 400718: 8fbf001c lw ra,28(sp)
33 40071c: 00001021 move v0,zero
34 400720: 03e00008 jr ra
35 400724: 27bd0020 addiu sp,sp,32 ; branch delay slot
36 ; NOP- - 16- :
37 400728: 00200825 move at,at
38 40072c: 00200825 move at,at
, x 64KiB, GP
( 18). : , (puts(),
scanf(), printf()) 64KiB GP ( 9, 16 26). GP ,
, , x
- . , .
NOP- (MOVE $AT,$AT ),
16- .
, x :
int x=10; //
IDA x .data:
77
7. SCANF() 7. SCANF()
.text:004006E8 lw $a1, x
; x $a1.
.text:004006EC la $t9, printf
.text:004006F0 lui $a0, 0x40
.text:004006F4 jalr $t9 ; printf
.text:004006F8 la $a0, aYouEnteredD___ # "You entered %d...\n"
.text:004006FC lw $ra, 0x20+var_4($sp)
.text:00400700 move $v0, $zero
.text:00400704 lw $s0, 0x20+var_8($sp)
.text:00400708 jr $ra
.text:0040070C addiu $sp, 0x20
...
.data:00410920 .globl x
.data:00410920 x: .word 0xA
78
7. SCANF() 7. SCANF()
7.3. scanf()
, scanf() .
, , scanf() - ,
scanf() .
#include <stdio.h>
int main()
{
int x;
printf ("Enter X:\n");
return 0;
};
, scanf()3 .
, , scanf() 1. , 0 ( EOF4 ).
, scanf() - .
:
C:\...>ex3.exe
Enter X:
123
You entered 123...
C:\...>ex3.exe
Enter X:
ouch
What you entered? Huh?
(MSVC 2010):
lea eax, DWORD PTR _x$[ebp]
push eax
push OFFSET $SG3833 ; '%d', 00H
call _scanf
add esp, 8
cmp eax, 1
jne SHORT $LN2@main
mov ecx, DWORD PTR _x$[ebp]
push ecx
push OFFSET $SG3834 ; 'You entered %d...', 0aH, 00H
call _printf
add esp, 8
jmp SHORT $LN1@main
$LN2@main:
push OFFSET $SG3836 ; 'What you entered? Huh?', 0aH, 00H
call _printf
add esp, 4
$LN1@main:
xor eax, eax
, (
scanf()) EAX.
3 scanf, wscanf: MSDN
4 End of le ( )
79
7. SCANF() 7. SCANF()
CMP EAX, 1 (CoMPare), EAX 1.
CMP: JNE. Jump if Not Equal,
.
, EAX 1, JNE CPU JNE, $LN2@main.
, CPU printf() What you entered? Huh?.
, printf() : 'You entered
%d...' x.
printf(), JMP, -
, printf() XOR EAX, EAX,
return 0.
, - -
CMP Jcc, cc condition code. CMP -
5 . Jcc ( ).
, , CMP SUB,
. ,
CMP. 1 1, , 0, ZF (zero ag),
, 0. EAX, ZF
, , . JNE ZF,
. , JNE JNZ (Jump if Not Zero).
. , CMP SUB ,
, SUB - . CMP SUB ,
.
, IDA. , MSVC
/MD, ,
MSVCR*.DLL. , .
IDA, ( ). . , ,
, JNZ . , n
error. exit. :
.text:00401000 _main proc near
.text:00401000
.text:00401000 var_4 = dword ptr 4
.text:00401000 argc = dword ptr 8
.text:00401000 argv = dword ptr 0Ch
.text:00401000 envp = dword ptr 10h
.text:00401000
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 push ecx
.text:00401004 push offset Format ; "Enter X:\n"
.text:00401009 call ds:printf
.text:0040100F add esp, 4
.text:00401012 lea eax, [ebp+var_4]
.text:00401015 push eax
.text:00401016 push offset aD ; "%d"
.text:0040101B call ds:scanf
.text:00401021 add esp, 8
.text:00401024 cmp eax, 1
.text:00401027 jnz short error
.text:00401029 mov ecx, [ebp+var_4]
.text:0040102C push ecx
.text:0040102D push offset aYou ; "You entered %d...\n"
.text:00401032 call ds:printf
.text:00401038 add esp, 8
.text:0040103B jmp short exit
.text:0040103D
.text:0040103D error: ; CODE XREF: _main+27
.text:0040103D push offset aWhat ; "What you entered? Huh?\n"
.text:00401042 call ds:printf
5 . x86-: wikipedia.
80
7. SCANF() 7. SCANF()
.text:00401048 add esp, 4
.text:0040104B
.text:0040104B exit: ; CODE XREF: _main+3B
.text:0040104B xor eax, eax
.text:0040104D mov esp, ebp
.text:0040104F pop ebp
.text:00401050 retn
.text:00401050 _main endp
. ,
.
IDA : ,
.
:
.text:00401000 _text segment para public 'CODE' use32
.text:00401000 assume cs:_text
.text:00401000 ;org 401000h
.text:00401000 ; ask for X
.text:00401012 ; get X
.text:00401024 cmp eax, 1
.text:00401027 jnz short error
.text:00401029 ; print result
.text:0040103B jmp short exit
.text:0040103D
.text:0040103D error: ; CODE XREF: _main+27
.text:0040103D push offset aWhat ; "What you entered? Huh?\n"
.text:00401042 call ds:printf
.text:00401048 add esp, 4
.text:0040104B
.text:0040104B exit: ; CODE XREF: _main+3B
.text:0040104B xor eax, eax
.text:0040104D mov esp, ebp
.text:0040104F pop ebp
.text:00401050 retn
.text:00401050 _main endp
+ .
81
7. SCANF() 7. SCANF()
, , IDA :
. 7.7: IDA
: . , -
, .
82
7. SCANF() 7. SCANF()
(group nodes). :
. 7.8: IDA
. , ( ) ,
.
83
7. SCANF() 7. SCANF()
7.3.3. MSVC: x86 + OllyDbg
OllyDbg , scanf() .
scanf() , .
0x6E494714:
84
7. SCANF() 7. SCANF()
scanf() , - , asdasd. scanf()
0 EAX, , :
. ,
scanf()? .
. EAX, , ,
Set to 1. .
EAX 1, , printf() .
(F9) :
. 7.11:
, 1850296084 (0x6E494714)!
85
7. SCANF() 7. SCANF()
7.3.4. MSVC: x86 + Hiew
.
, , .
MSVCR*.DLL (.. /MD)6 ,
main() .text. Hiew,
.text (Enter, F8, F6, Enter, Enter).
:
Hiew ASCIIZ7 - , .
6 , dynamic linking
7 ASCII Zero (ASCII- )
86
7. SCANF() 7. SCANF()
.00401027 ( JNZ, ), F3, -
9090( NOP-):
F9 (update). . , .
NOP- , , . 0
( ), JNZ .
: EB, ( ) .
. ,
.
_TEXT SEGMENT
x$ = 32
main PROC
$LN5:
87
7. SCANF() 7. SCANF()
sub rsp, 56
lea rcx, OFFSET FLAT:$SG2924 ; 'Enter X:'
call printf
lea rdx, QWORD PTR x$[rsp]
lea rcx, OFFSET FLAT:$SG2926 ; '%d'
call scanf
cmp eax, 1
jne SHORT $LN2@main
mov edx, DWORD PTR x$[rsp]
lea rcx, OFFSET FLAT:$SG2927 ; 'You entered %d...'
call printf
jmp SHORT $LN1@main
$LN2@main:
lea rcx, OFFSET FLAT:$SG2929 ; 'What you entered? Huh?'
call printf
$LN1@main:
; 0
xor eax, eax
add rsp, 56
ret 0
main ENDP
_TEXT ENDS
END
7.3.6. ARM
PUSH {R3,LR}
ADR R0, aEnterX ; "Enter X:\n"
BL __2printf
MOV R1, SP
ADR R0, aD ; "%d"
BL __0scanf
CMP R0, #1
BEQ loc_1E
ADR R0, aWhatYouEntered ; "What you entered? Huh?\n"
BL __2printf
: CMP BEQ8 .
CMP x86: .
BEQ , ,
0, Z 1. JZ x86.
: , , R0 0
.
ARM64
88
7. SCANF() 7. SCANF()
7.14: GCC 4.9.1 ARM64
1 .LC0:
2 .string "Enter X:"
3 .LC1:
4 .string "%d"
5 .LC2:
6 .string "You entered %d...\n"
7 .LC3:
8 .string "What you entered? Huh?"
9 f6:
10 ; FP LR :
11 stp x29, x30, [sp, 32]!
12 ; (FP=SP)
13 add x29, sp, 0
14 ; "Enter X:"
15 adrp x0, .LC0
16 add x0, x0, :lo12:.LC0
17 bl puts
18 ; "%d":
19 adrp x0, .LC1
20 add x0, x0, :lo12:.LC1
21 ; x
22 add x1, x29, 28
23 bl __isoc99_scanf
24 ; scanf() W0.
25 ; :
26 cmp w0, 1
27 ; BNE Branch if Not Equal (, )
28 ; W0<>0, L2
29 bne .L2
30 ; W0=1, ,
31 ; x
32 ldr w1, [x29,28]
33 ; "You entered %d...\n":
34 adrp x0, .LC2
35 add x0, x0, :lo12:.LC2
36 bl printf
37 ; , "What you entered? Huh?" :
38 b .L3
39 .L2:
40 ; "What you entered? Huh?" :
41 adrp x0, .LC3
42 add x0, x0, :lo12:.LC3
43 bl puts
44 .L3:
45 ; 0
46 mov w0, 0
47 ; FP LR:
48 ldp x29, x30, [sp], 32
49 ret
7.3.7. MIPS
89
7. SCANF() 7. SCANF()
.text:004006B4 la $t9, puts
.text:004006B8 lui $a0, 0x40
.text:004006BC jalr $t9 ; puts
.text:004006C0 la $a0, aEnterX # "Enter X:"
.text:004006C4 lw $gp, 0x28+var_18($sp)
.text:004006C8 lui $a0, 0x40
.text:004006CC la $t9, __isoc99_scanf
.text:004006D0 la $a0, aD # "%d"
.text:004006D4 jalr $t9 ; __isoc99_scanf
.text:004006D8 addiu $a1, $sp, 0x28+var_10 # branch delay slot
.text:004006DC li $v1, 1
.text:004006E0 lw $gp, 0x28+var_18($sp)
.text:004006E4 beq $v0, $v1, loc_40070C
.text:004006E8 or $at, $zero # branch delay slot, NOP
.text:004006EC la $t9, puts
.text:004006F0 lui $a0, 0x40
.text:004006F4 jalr $t9 ; puts
.text:004006F8 la $a0, aWhatYouEntered # "What you entered? Huh?"
.text:004006FC lw $ra, 0x28+var_4($sp)
.text:00400700 move $v0, $zero
.text:00400704 jr $ra
.text:00400708 addiu $sp, 0x28
.text:0040070C loc_40070C:
.text:0040070C la $t9, printf
.text:00400710 lw $a1, 0x28+var_10($sp)
.text:00400714 lui $a0, 0x40
.text:00400718 jalr $t9 ; printf
.text:0040071C la $a0, aYouEnteredD___ # "You entered %d...\n"
.text:00400720 lw $ra, 0x28+var_4($sp)
.text:00400724 move $v0, $zero
.text:00400728 jr $ra
.text:0040072C addiu $sp, 0x28
7.3.8.
7.4.
7.4.1. #1
int main()
{
alter_string ("Hello, world!\n");
};
: G.1.3 (. 986).
90
8. 8.
, .
?
8.1:
#include <stdio.h>
int main()
{
printf ("%d\n", f(1, 2, 3));
return 0;
};
8.1. x86
8.1.1. MSVC
_main PROC
push ebp
mov ebp, esp
push 3 ;
push 2 ;
push 1 ;
call _f
add esp, 12
push eax
push OFFSET $SG2463 ; '%d', 0aH, 00H
91
8. 8.
call _printf
add esp, 8
; 0
xor eax, eax
pop ebp
ret 0
_main ENDP
, : main() f(int,int,int).
f() , , : _a$ = 8, ,
, _a$ EBP,
EBP.
- : a EAX. EAX IMUL
, _b, EAX . EAX ,
_c. EAX , .
EAX printf().
OllyDbg. f(), -
(), , EBP . .
EBP, RA. ,
. EBP 8 (2 32-
).
OllyDbg , RETURN from Arg1 = , ..
N.B.: , . OllyDbg
Arg .
8.1.3. GCC
push ebp
92
8. 8.
mov ebp, esp
mov eax, [ebp+arg_0] ;
imul eax, [ebp+arg_4] ;
add eax, [ebp+arg_8] ;
pop ebp
retn
f endp
public main
main proc near
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
mov [esp+10h+var_8], 3 ;
mov [esp+10h+var_C], 2 ;
mov [esp+10h+var_10], 1 ;
call f
mov edx, offset aD ; "%d\n"
mov [esp+10h+var_C], eax
mov [esp+10h+var_10], edx
call _printf
mov eax, 0
leave
retn
main endp
, .
, LEAVE
(A.6.2 (. 965)) , .
8.2. x64
x86-64 , (4 6) , callee
, .
8.2.1. MSVC
MSVC:
main PROC
sub rsp, 40
mov edx, 2
lea r8d, QWORD PTR [rdx+1] ; R8D=3
lea ecx, QWORD PTR [rdx1] ; ECX=1
call f
lea rcx, OFFSET FLAT:$SG2997 ; '%d'
mov edx, eax
call printf
xor eax, eax
add rsp, 40
ret 0
main ENDP
f PROC
; ECX
; EDX
93
8. 8.
; R8D
imul ecx, edx
lea eax, DWORD PTR [r8+rcx]
ret 0
f ENDP
, f() . LEA
. , ADD. main()
LEA : , , LEA
, MOV.
MSVC:
; shadow space:
arg_0 = dword ptr 8
arg_8 = dword ptr 10h
arg_10 = dword ptr 18h
; ECX
; EDX
; R8D
mov [rsp+arg_10], r8d
mov [rsp+arg_8], edx
mov [rsp+arg_0], ecx
mov eax, [rsp+arg_0]
imul eax, [rsp+arg_8]
add eax, [rsp+arg_10]
retn
f endp
; 0
xor eax, eax
add rsp, 28h
retn
main endp
: 3 - . shadow space 1 :
Win64 ( ) 4- . -
: 1) ( 4 )
, ; 2) ,
2 .
, - shadows space ,
, , .
shadow space caller.
8.2.2. GCC
GCC :
1 MSDN
2 MSDN
94
8. 8.
f:
; EDI
; ESI
; EDX
imul esi, edi
lea eax, [rdx+rsi]
ret
main:
sub rsp, 8
mov edx, 3
mov esi, 2
mov edi, 1
call f
mov edi, OFFSET FLAT:.LC0 ; "%d\n"
mov esi, eax
xor eax, eax ;
call printf
xor eax, eax
add rsp, 8
ret
GCC:
95
8. 8.
uint64_t f (uint64_t a, uint64_t b, uint64_t c)
{
return a*b+c;
};
int main()
{
printf ("%lld\n", f(0x1122334455667788,
0x1111111122222222,
0x3333333344444444));
return 0;
};
, , , R-.
8.3. ARM
main() , (f()) .
, 4 ARM 4- (R0-R3).
f(), , (R0-R2) .
MLA (Multiply Accumulate) (R3 R1), -
(R2) (R0), , ,
.
96
8. 8.
3 (Fused multiplyadd) . , -
x86 FMA- SIMD4 .
MOV R3, R0, -, (
MLA). , , .
BX , LR , ,
Thumb ARM . , , , f() ,
, ARM Thumb. , Thumb, BX
, Thumb.
, ARM: [ARM12, A2.3.2].
.text:00000098 f
.text:00000098 91 20 20 E0 MLA R0, R1, R0, R2
.text:0000009C 1E FF 2F E1 BX LR
Thumb MLA , , -
. MULS R0 R1, R1. (ADDS)
R2, R0.
8.3.4. ARM64
. MADD , ( MLA,
). 3 32- X-. ,
32- int. W0.
main:
; FP LR :
stp x29, x30, [sp, 16]!
mov w2, 3
mov w1, 2
add x29, sp, 0
mov w0, 1
bl f
mov w1, w0
adrp x0, .LC7
add x0, x0, :lo12:.LC7
bl printf
; 0
mov w0, 0
; FP LR
ldp x29, x30, [sp], 16
3 Wikipedia: -
4 wikipedia
97
8. 8.
ret
.LC7:
.string "%d\n"
64- uint64_t :
#include <stdio.h>
#include <stdint.h>
int main()
{
printf ("%lld\n", f(0x1122334455667788,
0x1111111122222222,
0x3333333344444444));
return 0;
};
f:
madd x0, x0, x1, x2
ret
main:
mov x1, 13396
adrp x0, .LC8
stp x29, x30, [sp, 16]!
movk x1, 0x27d0, lsl 16
add x0, x0, :lo12:.LC8
movk x1, 0x122, lsl 32
add x29, sp, 0
movk x1, 0x58be, lsl 48
bl printf
mov w0, 0
ldp x29, x30, [sp], 16
ret
.LC8:
.string "%lld\n"
:
f:
sub sp, sp, #16
str w0, [sp,12]
str w1, [sp,8]
str w2, [sp,4]
ldr w1, [sp,12]
ldr w0, [sp,8]
mul w1, w1, w0
ldr w0, [sp,4]
add w0, w1, w0
add sp, sp, 16
ret
- ( -)
W0...W2, , -
. Register Save Area. [ARM13c] . Shadow
Space: 8.2.1 (. 94).
98
8. 8.
GCC 4.9 , , ?
, W0...W2
.
MUL/ ADD MADD.
8.4. MIPS
.text:00000010 main:
.text:00000010
.text:00000010 var_10 = 0x10
.text:00000010 var_4 = 4
.text:00000010
.text:00000010 lui $gp, (__gnu_local_gp >> 16)
.text:00000014 addiu $sp, 0x20
.text:00000018 la $gp, (__gnu_local_gp & 0xFFFF)
.text:0000001C sw $ra, 0x20+var_4($sp)
.text:00000020 sw $gp, 0x20+var_10($sp)
; c:
.text:00000024 li $a2, 3
; a:
.text:00000028 li $a0, 1
.text:0000002C jal f
; b:
.text:00000030 li $a1, 2 ; branch delay slot
; $v0
.text:00000034 lw $gp, 0x20+var_10($sp)
.text:00000038 lui $a0, ($LC0 >> 16)
.text:0000003C lw $t9, (printf & 0xFFFF)($gp)
.text:00000040 la $a0, ($LC0 & 0xFFFF)
.text:00000044 jalr $t9
; - f() printf():
.text:00000048 move $a1, $v0 ; branch delay slot
.text:0000004C lw $ra, 0x20+var_4($sp)
.text:00000050 move $v0, $zero
.text:00000054 jr $ra
.text:00000058 addiu $sp, 0x20 ; branch delay slot
4 A-.
MIPS : HI LO, 64- -
MULT. MFLO MFHI. MFLO
$V0. 32-
( HI ). , 32- int.
, ADDU (Add Unsigned ) .
MIPS : ADD ADDU. , , :
ADD . 5 , , Ada.
ADDU . /++ ,
ADDU ADD.
32- $V0.
main() : JAL (Jump and Link). JAL JALR ,
, JALR , (Jump
5 http://go.yurichev.com/17326
99
8. 8.
and Link Register). f() main() ,
f() .
100
9. 9.
x86 1 EAX,
(char), EAX AL. ,
FPU ST(0). ARM R0.
9.1. void
, , main() int, void?
.. startup- main() :
push envp
push argv
push argc
call main
push eax
call exit
:
exit(main(argc,argv,envp));
. , main() void:
#include <stdio.h>
void main()
{
printf ("Hello, world!\n");
};
Linux.
GCC 4.8.1 printf() puts() ( : 3.4.3 (. 15)) , , puts()
, printf(). , EAX
main(). EAX main() , puts() .
101
9. 9.
mov DWORD PTR [esp], OFFSET FLAT:.LC0
call puts
leave
ret
9.2: tst.sh
#!/bin/sh
./hello_world
echo $?
:
$ tst.sh
Hello, world!
14
14 .
9.2. ?
printf() , -
. , ,
:
int f()
{
// skip first 3 random values
rand();
rand();
rand();
// and use 4th
return rand();
};
9.3.
, EAX.
, , ( int),
, , . ,
, , .
, , , , .
, , ,
. ,
.
:
struct s
{
int a;
int b;
int c;
};
rt.a=a+1;
102
9. 9.
rt.b=a+2;
rt.c=a+3;
return rt;
};
$T3853 .
, C99:
struct s
{
int a;
int b;
int c;
};
, , .
. .
103
10. 10.
10
( scanf() (7 (. 61))).
, .
10.1.
#include <stdio.h>
void main()
{
f1(123, 456, &sum, &product);
printf ("sum=%d, product=%d\n", sum, product);
};
_x$ = 8 ; size = 4
_y$ = 12 ; size = 4
_sum$ = 16 ; size = 4
_product$ = 20 ; size = 4
_f1 PROC
mov ecx, DWORD PTR _y$[esp4]
mov eax, DWORD PTR _x$[esp4]
lea edx, DWORD PTR [eax+ecx]
imul eax, ecx
mov ecx, DWORD PTR _product$[esp4]
push esi
mov esi, DWORD PTR _sum$[esp]
mov DWORD PTR [esi], edx
mov DWORD PTR [ecx], eax
pop esi
ret 0
_f1 ENDP
_main PROC
push OFFSET _product
push OFFSET _sum
push 456 ; 000001c8H
104
10. 10.
push 123 ; 0000007bH
call _f1
mov eax, DWORD PTR _product
mov ecx, DWORD PTR _sum
push eax
push ecx
push OFFSET $SG2803
call DWORD PTR __imp__printf
add esp, 28 ; 0000001cH
xor eax, eax
ret 0
_main ENDP
105
10. 10.
OllyDbg:
106
10. 10.
, , Alt-M :
. 10.2: OllyDbg:
107
10. 10.
(F7) f1():
108
10. 10.
f1(). , :
109
10. 10.
printf():
10.2.
:
10.2:
void main()
{
int sum, product; // -
f1() . main():
110
10. 10.
OllyDbg. 0x2EF854 0x2EF858. , -
:
. 10.6: OllyDbg:
111
10. 10.
f1(). 0x2EF854 0x2EF858 :
112
10. 10.
f1():
10.3.
f1() . .
, references ++ . : (51.3 (. 580)).
113
11. GOTO 11. GOTO
11
GOTO
GOTO - [Dij68], ,
[Knu74], [Yur13, . 1.3.2].
:
#include <stdio.h>
int main()
{
printf ("begin\n");
goto exit;
printf ("skip me!\n");
exit:
printf ("end\n");
};
MSVC 2012:
_main PROC
push ebp
mov ebp, esp
push OFFSET $SG2934 ; 'begin'
call _printf
add esp, 4
jmp SHORT $exit$3
push OFFSET $SG2936 ; 'skip me!'
call _printf
add esp, 4
$exit$3:
push OFFSET $SG2937 ; 'end'
call _printf
add esp, 4
xor eax, eax
pop ebp
ret 0
_main ENDP
goto JMP, : .
printf() ,
.
114
11. GOTO 11. GOTO
. Hiew:
. 11.1: Hiew
115
11. GOTO 11. GOTO
JMP (0x410), F3 (), , EB
00:
. 11.2: Hiew
JMP . 0 .
JMP printf().
F9 () . :
. 11.3:
11.1.
printf() (dead code) . ,
. ,
:
_main PROC
push OFFSET $SG2981 ; 'begin'
call _printf
push OFFSET $SG2984 ; 'end'
$exit$4:
call _printf
add esp, 8
xor eax, eax
ret 0
_main ENDP
, skip me! .
116
11. GOTO 11. GOTO
11.2.
.
117
12. 12.
12
12.1.
#include <stdio.h>
int main()
{
f_signed(1, 2);
f_unsigned(1, 2);
return 0;
};
12.1.1. x86
x86 + MSVC
f_signed():
118
12. 12.
$LN3@f_signed:
mov ecx, DWORD PTR _a$[ebp]
cmp ecx, DWORD PTR _b$[ebp]
jne SHORT $LN2@f_signed
push OFFSET $SG739 ; 'a==b'
call _printf
add esp, 4
$LN2@f_signed:
mov edx, DWORD PTR _a$[ebp]
cmp edx, DWORD PTR _b$[ebp]
jge SHORT $LN4@f_signed
push OFFSET $SG741 ; 'a<b'
call _printf
add esp, 4
$LN4@f_signed:
pop ebp
ret 0
_f_signed ENDP
12.2: GCC
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_f_unsigned PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _a$[ebp]
cmp eax, DWORD PTR _b$[ebp]
jbe SHORT $LN3@f_unsigned
push OFFSET $SG2761 ; 'a>b'
call _printf
add esp, 4
$LN3@f_unsigned:
mov ecx, DWORD PTR _a$[ebp]
cmp ecx, DWORD PTR _b$[ebp]
jne SHORT $LN2@f_unsigned
push OFFSET $SG2763 ; 'a==b'
call _printf
add esp, 4
$LN2@f_unsigned:
mov edx, DWORD PTR _a$[ebp]
cmp edx, DWORD PTR _b$[ebp]
jae SHORT $LN4@f_unsigned
push OFFSET $SG2765 ; 'a<b'
call _printf
add esp, 4
$LN4@f_unsigned:
pop ebp
ret 0
_f_unsigned ENDP
119
12. 12.
12.3: main()
_main PROC
push ebp
mov ebp, esp
push 2
push 1
call _f_signed
add esp, 8
push 2
push 1
call _f_unsigned
add esp, 8
xor eax, eax
pop ebp
ret 0
_main ENDP
120
12. 12.
x86 + MSVC + OllyDbg
OllyDbg, , . f_unsigned(),
. CMP ,
, .
:
121
12. 12.
:
122
12. 12.
, JNB:
123
12. 12.
OllyDbg f_signed(), .
: C=1, P=1, A=1, Z=0, S=1, T=0, D=0, O=0.
JLE :
124
12. 12.
JNZ : ZF=0 (zero ag):
125
12. 12.
JGE , , SF=OF, :
126
12. 12.
x86 + MSVC + Hiew
, f_unsigned() a==b,
. Hiew:
, :
;
;
.
(code ow) printf(),
a==b.
( ):
JMP, (jump offset) .
,
, (jump offset) 0.
. 0,
.
JMP , , .
127
12. 12.
:
- , printf(),
.
GCC
GCC
, CMP , ?
, MSVC , GCC 4.8.1 :
128
12. 12.
mov DWORD PTR [esp+4], OFFSET FLAT:.LC1 ; "a==b"
jmp puts
12.1.2. ARM
32- ARM
129
12. 12.
.text:000000DC 04 00 55 E1 CMP R5, R4
.text:000000E0 70 80 BD A8 LDMGEFD SP!, {R4R6,PC}
.text:000000E4 70 40 BD E8 LDMFD SP!, {R4R6,LR}
.text:000000E8 19 0E 8F E2 ADR R0, aAB_1 ; "a<b\n"
.text:000000EC 99 18 00 EA B __2printf
.text:000000EC ; End of function f_signed
ARM .
.
, ADD ADDAL , AL Always, , .
4- 32- ARM- (condition eld). -
B , ,
AL condition eld, (execute ALways), .
ADRGT , ADR, , CMP, -
, , (Greater Than).
BLGT , BL ,
(Greater Than). ADRGT R0 a>b\n , BLGT printf(). , -
-GT , R0 ( a) , R4
( b).
ADREQ BLEQ. , ADR BL, -
. CMP, printf()
.
LDMGEFD. , LDMFD1 , -
(Greater or Equal).
LDMGEFD SP!, {R4-R6,PC} , , a >= b,
.
, a < b, LDMFD SP!, {R4-R6,LR}.
. R4-R6, LR PC, ,
, .
printf() a<b\n .
printf() printf() -
(6.2.1 (. 48)).
f_unsigned , ADRHI, BLHI, LDMCSFD. (HI =
Unsigned higher, CS = Carry Set (greater than or equal)) ,
.
main() :
12.7: main()
.text:00000128 EXPORT main
.text:00000128 main
.text:00000128 10 40 2D E9 STMFD SP!, {R4,LR}
.text:0000012C 02 10 A0 E3 MOV R1, #2
.text:00000130 01 00 A0 E3 MOV R0, #1
.text:00000134 DF FF FF EB BL f_signed
.text:00000138 02 10 A0 E3 MOV R1, #2
.text:0000013C 01 00 A0 E3 MOV R0, #1
.text:00000140 EA FF FF EB BL f_unsigned
.text:00000144 00 00 A0 E3 MOV R0, #0
.text:00000148 10 80 BD E8 LDMFD SP!, {R4,PC}
.text:00000148 ; End of function main
, ARM .
? : 33.1 (. 476).
x86 , CMOVcc, MOV,
, CMP .
1 LDMFD
130
12. 12.
Keil 6/2013 ( Thumb)
12.9: f_signed()
f_signed:
; W0=a, W1=b
cmp w0, w1
bgt .L19 ; Branch if Greater Than (, )(a>b)
beq .L20 ; Branch if Equal (, )(a==b)
bge .L15 ; Branch if Greater than or Equal (, )(a>=b) (
)
; a<b
adrp x0, .LC11 ; "a<b"
add x0, x0, :lo12:.LC11
b puts
.L19:
adrp x0, .LC9 ; "a>b"
add x0, x0, :lo12:.LC9
b puts
.L15: ;
ret
.L20:
adrp x0, .LC10 ; "a==b"
add x0, x0, :lo12:.LC10
b puts
12.10: f_unsigned()
f_unsigned:
stp x29, x30, [sp, 48]!
; W0=a, W1=b
cmp w0, w1
131
12. 12.
add x29, sp, 0
str x19, [sp,16]
mov w19, w0
bhi .L25 ; Branch if HIgher (, )(a>b)
cmp w19, w1
beq .L26 ; Branch if Equal (, )(a==b)
.L23:
bcc .L27 ; Branch if Carry Clear ( )( , ) (a<b)
; ,
ldr x19, [sp,16]
ldp x29, x30, [sp], 48
ret
.L27:
ldr x19, [sp,16]
adrp x0, .LC11 ; "a<b"
ldp x29, x30, [sp], 48
add x0, x0, :lo12:.LC11
b puts
.L25:
adrp x0, .LC9 ; "a>b"
str x1, [x29,40]
add x0, x0, :lo12:.LC9
bl puts
ldr x1, [x29,40]
cmp w19, w1
bne .L23 ; Branch if Not Equal (, )
.L26:
ldr x19, [sp,16]
adrp x0, .LC10 ; "a==b"
ldp x29, x30, [sp], 48
add x0, x0, :lo12:.LC10
b puts
. , ,
, - , .
, .
12.1.3. MIPS
MIPS . ,
(data dependency).
, SETcc x86: SLT (Set on Less Than ,
) SLTU ( ). - 1 0
.
- , BEQ (Branch on Equal ) BNE
(Branch on Not Equal ) .
MIPS .
:
132
12. 12.
.text:0000000C move $fp, $sp
.text:00000010 la $gp, __gnu_local_gp
.text:00000018 sw $gp, 0x20+var_10($sp)
; :
.text:0000001C sw $a0, 0x20+arg_0($fp)
.text:00000020 sw $a1, 0x20+arg_4($fp)
; reload them.
.text:00000024 lw $v1, 0x20+arg_0($fp)
.text:00000028 lw $v0, 0x20+arg_4($fp)
; $v0=b
; $v1=a
.text:0000002C or $at, $zero ; NOP
; . , "slt $v0,$v0,$v1" .
; $v0 1, $v0<$v1 (b<a) 0 :
.text:00000030 slt $v0, $v1
; loc_5c, .
; . , "beq $v0,$zero,loc_5c" :
.text:00000034 beqz $v0, loc_5C
; "a>b"
.text:00000038 or $at, $zero ; branch delay slot, NOP
.text:0000003C lui $v0, (unk_230 >> 16) # "a>b"
.text:00000040 addiu $a0, $v0, (unk_230 & 0xFFFF) # "a>b"
.text:00000044 lw $v0, (puts & 0xFFFF)($gp)
.text:00000048 or $at, $zero ; NOP
.text:0000004C move $t9, $v0
.text:00000050 jalr $t9
.text:00000054 or $at, $zero ; branch delay slot, NOP
.text:00000058 lw $gp, 0x20+var_10($fp)
.text:0000005C
.text:0000005C loc_5C: # CODE XREF: f_signed+34
.text:0000005C lw $v1, 0x20+arg_0($fp)
.text:00000060 lw $v0, 0x20+arg_4($fp)
.text:00000064 or $at, $zero ; NOP
; a==b, loc_90, :
.text:00000068 bne $v1, $v0, loc_90
.text:0000006C or $at, $zero ; branch delay slot, NOP
; , "a==b" :
.text:00000070 lui $v0, (aAB >> 16) # "a==b"
.text:00000074 addiu $a0, $v0, (aAB & 0xFFFF) # "a==b"
.text:00000078 lw $v0, (puts & 0xFFFF)($gp)
.text:0000007C or $at, $zero ; NOP
.text:00000080 move $t9, $v0
.text:00000084 jalr $t9
.text:00000088 or $at, $zero ; branch delay slot, NOP
.text:0000008C lw $gp, 0x20+var_10($fp)
.text:00000090
.text:00000090 loc_90: # CODE XREF: f_signed+68
.text:00000090 lw $v1, 0x20+arg_0($fp)
.text:00000094 lw $v0, 0x20+arg_4($fp)
.text:00000098 or $at, $zero ; NOP
; $v1<$v0 (a<b), $v0 1, :
.text:0000009C slt $v0, $v1, $v0
; (.. $v0==0), loc_c8:
.text:000000A0 beqz $v0, loc_C8
.text:000000A4 or $at, $zero ; branch delay slot, NOP
; , "a<b"
.text:000000A8 lui $v0, (aAB_0 >> 16) # "a<b"
.text:000000AC addiu $a0, $v0, (aAB_0 & 0xFFFF) # "a<b"
.text:000000B0 lw $v0, (puts & 0xFFFF)($gp)
.text:000000B4 or $at, $zero ; NOP
.text:000000B8 move $t9, $v0
.text:000000BC jalr $t9
.text:000000C0 or $at, $zero ; branch delay slot, NOP
.text:000000C4 lw $gp, 0x20+var_10($fp)
.text:000000C8
; 3 , :
.text:000000C8 loc_C8: # CODE XREF: f_signed+A0
.text:000000C8 move $sp, $fp
.text:000000CC lw $ra, 0x20+var_4($sp)
.text:000000D0 lw $fp, 0x20+var_8($sp)
133
12. 12.
.text:000000D4 addiu $sp, 0x20
.text:000000D8 jr $ra
.text:000000DC or $at, $zero ; branch delay slot, NOP
.text:000000DC # End of function f_signed
134
12. 12.
.text:00000198 move $t9, $v0
.text:0000019C jalr $t9
.text:000001A0 or $at, $zero
.text:000001A4 lw $gp, 0x20+var_10($fp)
.text:000001A8
.text:000001A8 loc_1A8: # CODE XREF: f_unsigned+A0
.text:000001A8 move $sp, $fp
.text:000001AC lw $ra, 0x20+var_4($sp)
.text:000001B0 lw $fp, 0x20+var_8($sp)
.text:000001B4 addiu $sp, 0x20
.text:000001B8 jr $ra
.text:000001BC or $at, $zero
.text:000001BC # End of function f_unsigned
12.2.
:
int my_abs (int i)
{
if (i<0)
return i;
else
return i;
};
12.2.1. MSVC
GCC 4.9 .
135
12. 12.
ARM , Keil Reverse Subtract,
, , .
ARM , Keil :
: 33.1 (. 476).
ARM64 NEG :
12.2.5. MIPS
12.2.6. ?
, : 45 (. 534).
136
12. 12.
12.3.
(ternary conditional operator) /++ :
expression ? expression : expression
:
const char* f (int a)
{
return a==10 ? "it is ten" : "it is not ten";
};
12.3.1. x86
, if/else
:
tv65 = 4 ;
_a$ = 8
_f PROC
push ebp
mov ebp, esp
push ecx
; 10
cmp DWORD PTR _a$[ebp], 10
; $LN3@f
jne SHORT $LN3@f
; :
mov DWORD PTR tv65[ebp], OFFSET $SG746 ; 'it is ten'
;
jmp SHORT $LN4@f
$LN3@f:
; :
mov DWORD PTR tv65[ebp], OFFSET $SG747 ; 'it is not ten'
$LN4@f:
; . EAX.
mov eax, DWORD PTR tv65[ebp]
mov esp, ebp
pop ebp
ret 0
_f ENDP
_a$ = 8 ; size = 4
_f PROC
; 10
cmp DWORD PTR _a$[esp4], 10
mov eax, OFFSET $SG792 ; 'it is ten'
; $LN4@f
je SHORT $LN4@f
mov eax, OFFSET $SG793 ; 'it is not ten'
$LN4@f:
ret 0
_f ENDP
137
12. 12.
12.20: MSVC 2012 x64
$SG1355 DB 'it is ten', 00H
$SG1356 DB 'it is not ten', 00H
a$ = 8
f PROC
;
lea rdx, OFFSET FLAT:$SG1355 ; 'it is ten'
lea rax, OFFSET FLAT:$SG1356 ; 'it is not ten'
; 10
cmp ecx, 10
; , RDX ("it is ten")
; , . "it is not ten" RAX.
cmove rax, rdx
ret 0
f ENDP
12.3.2. ARM
|L0.16|
DCB "it is ten",0
|L0.28|
DCB "it is not ten",0
ADREQ ADRNE .
Keil Thumb ,
, :
12.22: Keil 6/2013 ( Thumb)
f PROC
; 10
CMP r0,#0xa
; |L0.8| EQual ()
BEQ |L0.8|
ADR r0,|L0.12| ; "it is not ten"
BX lr
|L0.8|
ADR r0,|L0.28| ; "it is ten"
BX lr
ENDP
|L0.12|
DCB "it is not ten",0
|L0.28|
DCB "it is ten",0
12.3.3. ARM64
138
12. 12.
12.23: GCC (Linaro) 4.9
f:
cmp x0, 10
beq .L3 ; branch if equal (, )
adrp x0, .LC1 ; "it is ten"
add x0, x0, :lo12:.LC1
ret
.L3:
adrp x0, .LC0 ; "it is not ten"
add x0, x0, :lo12:.LC0
ret
.LC0:
.string "it is ten"
.LC1:
.string "it is not ten"
12.3.4. MIPS
$L2:
; "it is ten" $v0 :
lui $2,%hi($LC1)
j $31
addiu $2,$2,%lo($LC1)
12.3.5. , if/else
139
12. 12.
; 10
cmp DWORD PTR [esp+4], 10
mov edx, OFFSET FLAT:.LC1 ; "it is not ten"
mov eax, OFFSET FLAT:.LC0 ; "it is ten"
; Not Equal ( ), EDX EAX
; ,
cmovne eax, edx
ret
12.3.6.
? :
33.1 (. 476).
12.4.
12.4.1. 32-bit
_a$ = 8
_b$ = 12
_my_max PROC
push ebp
140
12. 12.
mov ebp, esp
mov eax, DWORD PTR _a$[ebp]
; A B:
cmp eax, DWORD PTR _b$[ebp]
; , A B:
jle SHORT $LN2@my_max
; A EAX
mov eax, DWORD PTR _a$[ebp]
jmp SHORT $LN3@my_max
jmp SHORT $LN3@my_max ; JMP
$LN2@my_max:
; B
mov eax, DWORD PTR _b$[ebp]
$LN3@my_max:
pop ebp
ret 0
_my_max ENDP
my_min PROC
; R0=A
; R1=B
; A B:
CMP r0,r1
; , A B:
BLT |L0.14|
; (A>=B) R1 (B):
MOVS r0,r1
|L0.14|
;
BX lr
ENDP
: BGT BLT.
ARM , . MOVcc
:
141
12. 12.
; B A B R0
; A<=B (.. LE - Less or Equal, )
; ( A>B), A R0
MOVLE r0,r1
BX lr
ENDP
my_min PROC
; R0=A
; R1=B
; A B:
CMP r0,r1
; B A B R0
; A>=B (.. GE - Greater or Equal, )
; ( A<B), A R0
MOVGE r0,r1
BX lr
ENDP
my_min:
mov edx, DWORD PTR [esp+4]
mov eax, DWORD PTR [esp+8]
; EDX=A
; EAX=B
; A B:
cmp edx, eax
; A<=B, A EAX
; , ( A>B)
cmovle eax, edx
ret
12.4.2. 64-bit
#include <stdint.h>
142
12. 12.
, :
my_min:
sub sp, sp, #16
str x0, [sp,8]
str x1, [sp]
ldr x1, [sp,8]
ldr x0, [sp]
cmp x1, x0
bge .L5
ldr x0, [sp,8]
b .L6
.L5:
ldr x0, [sp]
.L6:
add sp, sp, 16
ret
, :
my_min:
; RDI=A
; RSI=B
; A B:
cmp rdi, rsi
; B RAX :
mov rax, rsi
; A<=B, A (RDI) RAX .
; , ( A>B)
cmovle rax, rdi
ret
MSVC 2013 .
ARM64 CSEL, , MOVcc ARM CMOVcc x86, :
Conditional SELect.
143
12. 12.
12.32: GCC 4.9.1 ARM64
my_max:
; X0=A
; X1=B
; A B:
cmp x0, x1
; X0 (A) X0 X0>=X1 A>=B (Greater or Equal: )
; X1 (B) X0 A<B
csel x0, x0, x1, ge
ret
my_min:
; X0=A
; X1=B
; A B:
cmp x0, x1
; X0 (A) X0 X0<=X1 (Less or Equal: )
; X1 (B) X0 A>B
csel x0, x0, x1, le
ret
12.4.3. MIPS
locret_10:
jr $ra
or $at, $zero ; branch delay slot, NOP
; min() , SLT :
my_min:
slt $v1, $a0, $a1
beqz $v1, locret_28
move $v0, $a1
move $v0, $a0
locret_28:
jr $ra
or $at, $zero ; branch delay slot, NOP
12.5.
12.5.1. x86
12.34: x86
CMP register, register/value
Jcc true ; cc=
144
12. 12.
false:
... , , ...
JMP exit
true:
... , , ...
exit:
12.5.2. ARM
12.35: ARM
CMP register, register/value
Bcc true ; cc=
false:
... , , ...
JMP exit
true:
... , , ...
exit:
12.5.3. MIPS
12.36:
BEQZ REG, label
...
12.37: ?
BLTZ REG, label
...
12.38:
BEQ REG1, REG2, label
...
12.39:
BNE REG1, REG2, label
...
12.40: , ()
SLT REG1, REG2, REG3
BEQ REG1, label
...
12.41: , ()
SLTU REG1, REG2, REG3
BEQ REG1, label
...
12.5.4.
, : MOVcc
ARM ( ARM), CSEL ARM64, CMOVcc x86.
145
12. 12.
ARM
ARM :
, CPU
.
Thumb IT, 4 , .
: 17.7.2 (. 260).
12.6.
(ARM64) .12.23 , -
CSEL.
146
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
13
switch()/case/default
13.1.
#include <stdio.h>
void f (int a)
{
switch (a)
{
case 0: printf ("zero\n"); break;
case 1: printf ("one\n"); break;
case 2: printf ("two\n"); break;
default: printf ("something unknown\n"); break;
};
};
int main()
{
f (2); // test
};
13.1.1. x86
MSVC
(MSVC 2010):
147
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
call _printf
add esp, 4
jmp SHORT $LN7@f
$LN2@f:
push OFFSET $SG743 ; 'two', 0aH, 00H
call _printf
add esp, 4
jmp SHORT $LN7@f
$LN1@f:
push OFFSET $SG745 ; 'something unknown', 0aH, 00H
call _printf
add esp, 4
$LN7@f:
mov esp, ebp
pop ebp
ret 0
_f ENDP
switch(), , -
:
void f (int a)
{
if (a==0)
printf ("zero\n");
else if (a==1)
printf ("one\n");
else if (a==2)
printf ("two\n");
else
printf ("something unknown\n");
};
, , -
switch(), if(). , switch()
if().
, , -
(a) v641 .
GCC 4.4.1, , (
-O3).
MSVC
13.2: MSVC
_a$ = 8 ; size = 4
_f PROC
mov eax, DWORD PTR _a$[esp4]
sub eax, 0
je SHORT $LN4@f
sub eax, 1
je SHORT $LN3@f
sub eax, 1
je SHORT $LN2@f
mov DWORD PTR _a$[esp4], OFFSET $SG791 ; 'something unknown', 0aH, 00H
jmp _printf
$LN2@f:
mov DWORD PTR _a$[esp4], OFFSET $SG789 ; 'two', 0aH, 00H
jmp _printf
$LN3@f:
mov DWORD PTR _a$[esp4], OFFSET $SG787 ; 'one', 0aH, 00H
jmp _printf
$LN4@f:
mov DWORD PTR _a$[esp4], OFFSET $SG785 ; 'zero', 0aH, 00H
1 tv MSVC
148
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
jmp _printf
_f ENDP
-, .
: EAX 0. , , , 0 EAX
? , ZF ( , 0 0)
JE (Jump if Equal JZ Jump if Zero) $LN4@f,
'zero'. , , -
0, .
, , printf()
'something unknown'.
: , , : a,
printf() CALL, JMP. .
CALL . CALL (RA)
. ( ,
, - ESP) :
ESP RA
ESP+4 a
, printf(), ,
. , , .
, printf(),
f(), printf(). printf() stdout, RET,
RA , f(),
f().
, printf() f() . - longjmp()2 .
, , .
ARM printf() (6.2.1 (. 48)).
2 wikipedia
149
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
OllyDbg
, OllyDbg.
150
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
0 2 EAX. , EAX 2. ZF 0, , -
:
151
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
DEC EAX 1. 1 , ZF 0:
152
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
DEC . EAX 0 ZF , :
OllyDbg , .
153
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
two :
. 13.5: OllyDbg:
: 2 2 0x001EF850.
154
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
MOV 0x001EF850 (. ). . -
printf() MSVCR100.DLL ( /MD):
printf() 0x00FF3010 .
155
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
printf():
two .
156
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
F7 F8 ( , ) , f() main():
, printf() main(). RA -
f() main(). CALL 0x00FF1000 f().
.text:0000014C f1:
.text:0000014C 00 00 50 E3 CMP R0, #0
.text:00000150 13 0E 8F 02 ADREQ R0, aZero ; "zero\n"
.text:00000154 05 00 00 0A BEQ loc_170
.text:00000158 01 00 50 E3 CMP R0, #1
.text:0000015C 4B 0F 8F 02 ADREQ R0, aOne ; "one\n"
.text:00000160 02 00 00 0A BEQ loc_170
.text:00000164 02 00 50 E3 CMP R0, #2
.text:00000168 4A 0F 8F 12 ADRNE R0, aSomethingUnkno ; "something unknown\n"
.text:0000016C 4E 0F 8F 02 ADREQ R0, aTwo ; "two\n"
.text:00000170
.text:00000170 loc_170: ; CODE XREF: f1+8
.text:00000170 ; f1+14
.text:00000170 78 18 00 EA B __2printf
, , switch()
if().
, , , ADREQ ((Equal)),
R0 = 0, R0 zero\n. BEQ
loc_170, R0 = 0.
, , BEQ , ADREQ
R0 - ? , BEQ , CMP, ADREQ
.
. printf() , , (6.2.1
(. 48)). printf() .
CMP R0, #2 , a = 2 . , ADRNE (Not
Equal) R0 something unknown \n, a 0 1 ,
a . R0 = 2, R0 two\n
ADREQ.
157
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
13.1.3. ARM: Keil 6/2013 ( Thumb)
.text:000000D4 f1:
.text:000000D4 10 B5 PUSH {R4,LR}
.text:000000D6 00 28 CMP R0, #0
.text:000000D8 05 D0 BEQ zero_case
.text:000000DA 01 28 CMP R0, #1
.text:000000DC 05 D0 BEQ one_case
.text:000000DE 02 28 CMP R0, #2
.text:000000E0 05 D0 BEQ two_case
.text:000000E2 91 A0 ADR R0, aSomethingUnkno ; "something unknown\n"
.text:000000E4 04 E0 B default_case
, Thumb- ,
Thumb- x86 CISC, .
.LC12:
.string "zero"
.LC13:
.string "one"
.LC14:
.string "two"
.LC15:
.string "something unknown"
f12:
stp x29, x30, [sp, 32]!
add x29, sp, 0
str w0, [x29,28]
ldr w0, [x29,28]
cmp w0, 1
beq .L34
cmp w0, 2
beq .L35
cmp w0, wzr
bne .L38 ;
adrp x0, .LC12 ; "zero"
add x0, x0, :lo12:.LC12
bl puts
b .L32
.L34:
adrp x0, .LC13 ; "one"
add x0, x0, :lo12:.LC13
bl puts
b .L32
.L35:
adrp x0, .LC14 ; "two"
add x0, x0, :lo12:.LC14
bl puts
b .L32
.L38:
adrp x0, .LC15 ; "something unknown"
158
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
add x0, x0, :lo12:.LC15
bl puts
nop
.L32:
ldp x29, x30, [sp], 32
ret
f12:
cmp w0, 1
beq .L31
cmp w0, 2
beq .L32
cbz w0, .L35
;
adrp x0, .LC15 ; "something unknown"
add x0, x0, :lo12:.LC15
b puts
.L35:
adrp x0, .LC12 ; "zero"
add x0, x0, :lo12:.LC12
b puts
.L32:
adrp x0, .LC14 ; "two"
add x0, x0, :lo12:.LC14
b puts
.L31:
adrp x0, .LC13 ; "one"
add x0, x0, :lo12:.LC13
b puts
13.1.6. MIPS
159
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
lui $a0, ($LC3 >> 16) # "something unknown"
lw $t9, (puts & 0xFFFF)($gp)
or $at, $zero ; load delay slot, NOP
jr $t9
la $a0,
($LC3 & 0xFFFF) # "something unknown" ; branch delay slot
#
13.1.7.
13.2.
, JE/ JNE .
#include <stdio.h>
void f (int a)
{
switch (a)
{
case 0: printf ("zero\n"); break;
case 1: printf ("one\n"); break;
case 2: printf ("two\n"); break;
case 3: printf ("three\n"); break;
case 4: printf ("four\n"); break;
default: printf ("something unknown\n"); break;
};
};
int main()
{
f (2); // test
};
13.2.1. x86
MSVC
, (MSVC 2010):
160
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
13.4: MSVC 2010
tv64 = 4 ; size = 4
_a$ = 8 ; size = 4
_f PROC
push ebp
mov ebp, esp
push ecx
mov eax, DWORD PTR _a$[ebp]
mov DWORD PTR tv64[ebp], eax
cmp DWORD PTR tv64[ebp], 4
ja SHORT $LN1@f
mov ecx, DWORD PTR tv64[ebp]
jmp DWORD PTR $LN11@f[ecx*4]
$LN6@f:
push OFFSET $SG739 ; 'zero', 0aH, 00H
call _printf
add esp, 4
jmp SHORT $LN9@f
$LN5@f:
push OFFSET $SG741 ; 'one', 0aH, 00H
call _printf
add esp, 4
jmp SHORT $LN9@f
$LN4@f:
push OFFSET $SG743 ; 'two', 0aH, 00H
call _printf
add esp, 4
jmp SHORT $LN9@f
$LN3@f:
push OFFSET $SG745 ; 'three', 0aH, 00H
call _printf
add esp, 4
jmp SHORT $LN9@f
$LN2@f:
push OFFSET $SG747 ; 'four', 0aH, 00H
call _printf
add esp, 4
jmp SHORT $LN9@f
$LN1@f:
push OFFSET $SG749 ; 'something unknown', 0aH, 00H
call _printf
add esp, 4
$LN9@f:
mov esp, ebp
pop ebp
ret 0
npad 2 ;
$LN11@f:
DD $LN6@f ; 0
DD $LN5@f ; 1
DD $LN4@f ; 2
DD $LN3@f ; 3
DD $LN2@f ; 4
_f ENDP
: printf() . ,
, , , .
$LN11@f.
, a 4, $LN1@f, printf() -
'something unknown'.
a 4, 4 ($LN11@f).
, , . ,
a 2. 2 4 = 8 ( 32- , ,
4 ). 8 $LN11@f , $LN4@f. JMP
$LN4@f .
jumptable branch table3 .
3 computed GOTO FORTRAN: wikipedia. - , !
161
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
printf() 'two'. , jmp DWORD PTR $LN11@f[ecx*4]
DWORD, $LN11@f + ecx * 4.
npad (88 (. 895)) , , -
4 ( 16). , 32-
, -, ..
162
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
OllyDbg
163
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
, 4? , (default) :
. 13.10: OllyDbg: 2 4:
164
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
jumptable:
165
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
0x010B103A: , two:
GCC
, GCC 4.4.1:
push ebp
mov ebp, esp
sub esp, 18h
cmp [ebp+arg_0], 4
ja short loc_8048444
mov eax, [ebp+arg_0]
shl eax, 2
mov eax, ds:off_804855C[eax]
jmp eax
166
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
mov [esp+18h+var_18], offset aThree ; "three"
call _puts
jmp short locret_8048450
, : arg_0 4
2 ( 4) (16.2.1 (. 215)).
off_804855C .
00000180
00000180 loc_180 ; CODE XREF: f2+4
00000180 03 00 00 EA B zero_case ; jumptable 00000178 case 0
00000184
00000184 loc_184 ; CODE XREF: f2+4
00000184 04 00 00 EA B one_case ; jumptable 00000178 case 1
00000188
00000188 loc_188 ; CODE XREF: f2+4
00000188 05 00 00 EA B two_case ; jumptable 00000178 case 2
0000018C
0000018C loc_18C ; CODE XREF: f2+4
0000018C 06 00 00 EA B three_case ; jumptable 00000178 case 3
00000190
00000190 loc_190 ; CODE XREF: f2+4
00000190 07 00 00 EA B four_case ; jumptable 00000178 case 4
00000194
00000194 zero_case ; CODE XREF: f2+4
00000194 ; f2:loc_180
00000194 EC 00 8F E2 ADR R0, aZero ; jumptable 00000178 case 0
00000198 06 00 00 EA B loc_1B8
0000019C
0000019C one_case ; CODE XREF: f2+4
0000019C ; f2:loc_184
0000019C EC 00 8F E2 ADR R0, aOne ; jumptable 00000178 case 1
167
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
000001A0 04 00 00 EA B loc_1B8
000001A4
000001A4 two_case ; CODE XREF: f2+4
000001A4 ; f2:loc_188
000001A4 01 0C 8F E2 ADR R0, aTwo ; jumptable 00000178 case 2
000001A8 02 00 00 EA B loc_1B8
000001AC
000001AC three_case ; CODE XREF: f2+4
000001AC ; f2:loc_18C
000001AC 01 0C 8F E2 ADR R0, aThree ; jumptable 00000178 case 3
000001B0 00 00 00 EA B loc_1B8
000001B4
000001B4 four_case ; CODE XREF: f2+4
000001B4 ; f2:loc_190
000001B4 01 0C 8F E2 ADR R0, aFour ; jumptable 00000178 case 4
000001B8
000001B8 loc_1B8 ; CODE XREF: f2+24
000001B8 ; f2+2C
000001B8 66 18 00 EA B __2printf
000001BC
000001BC default_case ; CODE XREF: f2+4
000001BC ; f2+8
000001BC D4 00 8F E2 ADR R0, aSomethingUnkno ; jumptable 00000178 default case
000001C0 FC FF FF EA B loc_1B8
ARM,
4 .
, , a 4: , something
unknown\n.
CMP R0, #5 a c 5.
ADDCC PC, PC, R0,LSL#2 5 R0 < 5 (CC=Carry clear / Less than).
, ADDCC ( R0 5), default_case.
R0 < 5 ADDCC , .
R0 4. , LSL#2 2 .
(16.2.1 (. 215)) , 2 e 4.
R0 4 PC, , , -
B (Branch).
ADDCC, PC 8 (0x180),
ADDCC (0x178), , , 2 .
ARM: ADDCC, -
, PC . .
a = 0, PC PC PC (
8) loc_180. 8 , ADDCC.
a = 1, PC P C + 8 + a 4 = P C + 8 + 1 4 = P C + 12 = 0x184. loc_184.
a PC 4. 4 ARM -
, B, 5 .
B , ,
switch(). , ..
168
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
000000F6 10 B5 PUSH {R4,LR}
000000F8 03 00 MOVS R3, R0
000000FA 06 F0 69 F8 BL __ARM_common_switch8_thumb ; switch 6 cases
000000FE 05 DCB 5
000000FF 04 06 08 0A 0C 10 DCB 4, 6, 8, 0xA, 0xC, 0x10 ; jump table for switch statement
00000105 00 ALIGN 2
00000106
00000106 zero_case ; CODE XREF: f2+4
00000106 8D A0 ADR R0, aZero ; jumptable 000000FA case 0
00000108 06 E0 B loc_118
0000010A
0000010A one_case ; CODE XREF: f2+4
0000010A 8E A0 ADR R0, aOne ; jumptable 000000FA case 1
0000010C 04 E0 B loc_118
0000010E
0000010E two_case ; CODE XREF: f2+4
0000010E 8F A0 ADR R0, aTwo ; jumptable 000000FA case 2
00000110 02 E0 B loc_118
00000112
00000112 three_case ; CODE XREF: f2+4
00000112 90 A0 ADR R0, aThree ; jumptable 000000FA case 3
00000114 00 E0 B loc_118
00000116
00000116 four_case ; CODE XREF: f2+4
00000116 91 A0 ADR R0, aFour ; jumptable 000000FA case 4
00000118
00000118 loc_118 ; CODE XREF: f2+12
00000118 ; f2+16
00000118 06 F0 6A F8 BL __2printf
0000011C 10 BD POP {R4,PC}
0000011E
0000011E default_case ; CODE XREF: f2+4
0000011E 82 A0 ADR R0, aSomethingUnkno ; jumptable 000000FA default case
00000120 FA E7 B loc_118
000061D2 00 00 ALIGN 4
000061D2 ; End of function __ARM_common_switch8_thumb
000061D2
000061D4 __32__ARM_common_switch8_thumb ; CODE XREF: __ARM_common_switch8_thumb
000061D4 01 C0 5E E5 LDRB R12, [LR,#1]
000061D8 0C 00 53 E1 CMP R3, R12
000061DC 0C 30 DE 27 LDRCSB R3, [LR,R12]
000061E0 03 30 DE 37 LDRCCB R3, [LR,R3]
000061E4 83 C0 8E E0 ADD R12, LR, R3,LSL#1
000061E8 1C FF 2F E1 BX R12
000061E8 ; End of function __32__ARM_common_switch8_thumb
Thumb Thumb-2 , . ,
, x86.
, , ,
, , . ,
.
, __ARM_common_switch8_thumb.
BX PC , ARM-. ,
. , .
169
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
, LR . ,
, LR BL __ARM_common_switch8_thumb ,
.
, , -
switch().
IDA
jumptable 000000FA case 0.
13.2.4. MIPS
170
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
lui $a0, ($LC1 >> 16) # "one"
lw $t9, (puts & 0xFFFF)($gp)
or $at, $zero ; NOP
jr $t9
la $a0, ($LC1 & 0xFFFF) # "one" ; branch delay slot
; .rodata:
off_120: .word sub_6C
.word sub_80
.word sub_94
.word sub_44
.word sub_58
13.2.5.
switch():
13.9: x86
MOV REG, input
CMP REG, 4 ;
JA default
SHL REG, 2 ; . 3 x64
MOV REG, jump_table[REG]
JMP REG
case1:
; -
JMP exit
case2:
; -
JMP exit
case3:
; -
JMP exit
case4:
; -
JMP exit
case5:
; -
JMP exit
default:
...
exit:
....
jump_table dd case1
dd case2
dd case3
171
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
dd case4
dd case5
: JMP jump_table[REG*4].
JMP jump_table[REG*8] x64.
(jumptable) , : 18.5 (. 285).
13.3. case
: case :
#include <stdio.h>
void f(int a)
{
switch (a)
{
case 1:
case 2:
case 7:
case 10:
printf ("1, 2, 7, 10\n");
break;
case 3:
case 4:
case 5:
case 6:
printf ("3, 4, 5\n");
break;
case 8:
case 9:
case 20:
case 21:
printf ("8, 9, 21\n");
break;
case 22:
printf ("22\n");
break;
default:
printf ("default\n");
break;
};
};
int main()
{
f(4);
};
,
.
13.3.1. MSVC
172
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
11 cmp eax, 21
12 ja SHORT $LN1@f
13 movzx eax, BYTE PTR $LN10@f[eax]
14 jmp DWORD PTR $LN11@f[eax*4]
15 $LN5@f:
16 mov DWORD PTR _a$[esp4], OFFSET $SG2798 ; '1, 2, 7, 10'
17 jmp DWORD PTR __imp__printf
18 $LN4@f:
19 mov DWORD PTR _a$[esp4], OFFSET $SG2800 ; '3, 4, 5'
20 jmp DWORD PTR __imp__printf
21 $LN3@f:
22 mov DWORD PTR _a$[esp4], OFFSET $SG2802 ; '8, 9, 21'
23 jmp DWORD PTR __imp__printf
24 $LN2@f:
25 mov DWORD PTR _a$[esp4], OFFSET $SG2804 ; '22'
26 jmp DWORD PTR __imp__printf
27 $LN1@f:
28 mov DWORD PTR _a$[esp4], OFFSET $SG2806 ; 'default'
29 jmp DWORD PTR __imp__printf
30 npad 2 ; $LN11@f 16-
31 $LN11@f:
32 DD $LN5@f ; '1, 2, 7, 10'
33 DD $LN4@f ; '3, 4, 5'
34 DD $LN3@f ; '8, 9, 21'
35 DD $LN2@f ; '22'
36 DD $LN1@f ; 'default'
37 $LN10@f:
38 DB 0 ; a=1
39 DB 0 ; a=2
40 DB 1 ; a=3
41 DB 1 ; a=4
42 DB 1 ; a=5
43 DB 1 ; a=6
44 DB 0 ; a=7
45 DB 2 ; a=8
46 DB 2 ; a=9
47 DB 0 ; a=10
48 DB 4 ; a=11
49 DB 4 ; a=12
50 DB 4 ; a=13
51 DB 4 ; a=14
52 DB 4 ; a=15
53 DB 4 ; a=16
54 DB 4 ; a=17
55 DB 4 ; a=18
56 DB 4 ; a=19
57 DB 2 ; a=20
58 DB 2 ; a=21
59 DB 3 ; a=22
60 _f ENDP
: ($LN10@f) , ($LN11@f)
.
, ( 13).
: 0 case ( 1, 2, 7, 10), 1 (
3, 4, 5), 2 ( 8, 9, 21), 3 ( 22), 4 .
( 14).
, . DEC
10 a = 1. a = 0.
.
? , (13.2.1 (. 166)), ,
? , 8- ,
.
173
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
13.3.2. GCC
-, , 0, GCC
, 1.
GCC 4.9.1 ARM64 . 8- .
, ARM64 4 . GCC ,
. .
174
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
; "22"
adrp x0, .LC3
add x0, x0, :lo12:.LC3
b puts
.L6:
; "8, 9, 21"
adrp x0, .LC2
add x0, x0, :lo12:.LC2
b puts
.L5:
; "3, 4, 5"
adrp x0, .LC1
add x0, x0, :lo12:.LC1
b puts
.L3:
; "1, 2, 7, 10"
adrp x0, .LC0
add x0, x0, :lo12:.LC0
b puts
.LC0:
.string "1, 2, 7, 10"
.LC1:
.string "3, 4, 5"
.LC2:
.string "8, 9, 21"
.LC3:
.string "22"
.LC4:
.string "default"
IDA. :
1, 9 9 Lrtx4. 22, 0 4,
0. Lrtx4 L7, , 22.
, .rodata ( ).
(0xF7). , , default
( .L2).
175
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
13.4. Fall-through
switch() .. fallthrough (). :
1 #define R 1
2 #define W 2
3 #define RW 3
4
5 void f(int type)
6 {
7 int read=0, write=0;
8
9 switch (type)
10 {
11 case RW:
12 read=1;
13 case W:
14 write=1;
15 break;
16 case R:
17 read=1;
18 break;
19 default:
20 break;
21 };
22 printf ("read=%d, write=%d\n", read, write);
23 };
_write$ = 12 ; size = 4
_read$ = 8 ; size = 4
tv64 = 4 ; size = 4
_type$ = 8 ; size = 4
_f PROC
push ebp
mov ebp, esp
sub esp, 12
mov DWORD PTR _read$[ebp], 0
mov DWORD PTR _write$[ebp], 0
mov eax, DWORD PTR _type$[ebp]
mov DWORD PTR tv64[ebp], eax
cmp DWORD PTR tv64[ebp], 1 ; R
je SHORT $LN2@f
cmp DWORD PTR tv64[ebp], 2 ; W
je SHORT $LN3@f
cmp DWORD PTR tv64[ebp], 3 ; RW
je SHORT $LN4@f
jmp SHORT $LN5@f
$LN4@f: ; case RW:
mov DWORD PTR _read$[ebp], 1
$LN3@f: ; case W:
mov DWORD PTR _write$[ebp], 1
jmp SHORT $LN5@f
$LN2@f: ; case R:
mov DWORD PTR _read$[ebp], 1
$LN5@f: ; default
mov ecx, DWORD PTR _write$[ebp]
push ecx
176
13. SWITCH()/CASE/DEFAULT 13. SWITCH()/CASE/DEFAULT
mov edx, DWORD PTR _read$[ebp]
push edx
push OFFSET $SG1305 ; 'read=%d, write=%d'
call _printf
add esp, 12
mov esp, ebp
pop ebp
ret 0
_f ENDP
, . $LN4@f $LN3@f:
(code ow) $LN4@f, read 1, write. ,
: ( read)
( write). type = W , $LN3@f, read 1 .
13.4.2. ARM64
. .L4 .L3.
13.5.
13.5.1. #1
13.2 (. 160) ,
, . .
: G.1.5 (. 986).
177
14. 14.
14
14.1.
14.1.1. x86
, .
:
#include <stdio.h>
void printing_function(int i)
{
printf ("f(%d)\n", i);
};
int main()
{
int i;
return 0;
};
(MSVC 2010):
178
14. 14.
$LN2@main:
mov eax, DWORD PTR _i$[ebp] ; :
add eax, 1 ; 1 i
mov DWORD PTR _i$[ebp], eax
$LN3@main:
cmp DWORD PTR _i$[ebp], 10 ; **
jge SHORT $LN1@main ; i 10,
mov ecx, DWORD PTR _i$[ebp] ; : printing_function(i)
push ecx
call _printing_function
add esp, 4
jmp SHORT $LN2@main ;
$LN1@main: ;
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
, .
GCC 4.4.1 , :
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 20h
mov [esp+20h+var_4], 2 ; i
jmp short loc_8048476
loc_8048465:
mov eax, [esp+20h+var_4]
mov [esp+20h+var_20], eax
call printing_function
add [esp+20h+var_4], 1 ; i
loc_8048476:
cmp [esp+20h+var_4], 9
jle short loc_8048465 ; i<=9,
mov eax, 0
leave
retn
main endp
14.3: MSVC
_main PROC
push esi
mov esi, 2
$LL3@main:
push esi
call _printing_function
inc esi
add esp, 4
cmp esi, 10 ; 0000000aH
jl SHORT $LL3@main
xor eax, eax
pop esi
ret 0
_main ENDP
179
14. 14.
: i ,
: ESI. , .
, , : f() ESI. -
, ESI f(),
. : PUSH ESI/POP ESI
.
GCC 4.4.1 (-O3):
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
mov [esp+10h+var_10], 2
call printing_function
mov [esp+10h+var_10], 3
call printing_function
mov [esp+10h+var_10], 4
call printing_function
mov [esp+10h+var_10], 5
call printing_function
mov [esp+10h+var_10], 6
call printing_function
mov [esp+10h+var_10], 7
call printing_function
mov [esp+10h+var_10], 8
call printing_function
mov [esp+10h+var_10], 9
call printing_function
xor eax, eax
leave
retn
main endp
GCC 1 .
, ( ) ,
, . , .
, -
-2 .
i 100 . GCC :
14.5: GCC
public main
main proc near
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
push ebx
mov ebx, 2 ; i=2
sub esp, 1Ch
; loc_80484D0 ( ) 16- :
nop
loc_80484D0:
; i printing_function():
1 loop unwinding
2 : [Dre07]. Intel : [Int14, . 3.4.1.7].
180
14. 14.
mov [esp+20h+var_20], ebx
add ebx, 1 ; i++
call printing_function
cmp ebx, 64h ; i==100?
jnz short loc_80484D0 ; ,
add esp, 1Ch
xor eax, eax ; 0
pop ebx
mov esp, ebp
pop ebp
retn
main endp
181
14. 14.
14.1.2. x86: OllyDbg
. 14.2: OllyDbg: i = 6
9 . JL :
, . tracer.
IDA, PUSH ESI (
f(),) 0x401026 tracer:
tracer.exe l:loops_2.exe bpx=loops_2.exe!0x00401026
BPX tracer .
tracer.log :
182
14. 14.
, ESI 2 9.
, tracer .
trace. , . .idc-
IDA, . , IDA main() 0x00401020 :
tracer.exe l:loops_2.exe bpf=loops_2.exe!0x00401020,trace:cc
BPF .
loops_2.exe.idc loops_2.exe_clear.idc.
183
14. 14.
loops_2.exe.idc IDA :
, ESI 2 9 , [3..0xA]. ,
main() 0 EAX.
tracer loops_2.exe.txt, , -
:
14.6: loops_2.exe.txt
0x401020 (.text+0x20), e= 1 [PUSH ESI] ESI=1
0x401021 (.text+0x21), e= 1 [MOV ESI, 2]
0x401026 (.text+0x26), e= 8 [PUSH ESI] ESI=2..9
0x401027 (.text+0x27), e= 8 [CALL 8D1000h] tracing nested maximum level (1) reached, skipping
this CALL 8D1000h=0x8d1000
0x40102c (.text+0x2c), e= 8 [INC ESI] ESI=2..9
0x40102d (.text+0x2d), e= 8 [ADD ESP, 4] ESP=0x38fcbc
0x401030 (.text+0x30), e= 8 [CMP ESI, 0Ah] ESI=3..0xa
0x401033 (.text+0x33), e= 8 [JL 8D1026h] SF=false,true OF=false
0x401035 (.text+0x35), e= 1 [XOR EAX, EAX]
0x401037 (.text+0x37), e= 1 [POP ESI]
0x401038 (.text+0x38), e= 1 [RETN] EAX=0
grep.
14.1.4. ARM
main
STMFD SP!, {R4,LR}
MOV R4, #2
B loc_368
loc_35C ; CODE XREF: main+1C
MOV R0, R4
BL printing_function
ADD R4, R4, #1
184
14. 14.
BLT loc_35C
MOV R0, #0
LDMFD SP!, {R4,PC}
i R4.
MOV R4, #2 i.
MOV R0, R4 BL printing_function .,
, f() .
ADD R4, R4, #1 i .
CMP R4, #0xA i 0xA (10). BLT (Branch Less Than) ,
i 10.
R0 0 ( 0) .
_main
PUSH {R4,LR}
MOVS R4, #2
_main
PUSH {R4,R7,LR}
MOVW R4, #0x1124 ; "%d\n"
MOVS R1, #2
MOVT.W R4, #0
ADD R7, SP, #4
ADD R4, PC
MOV R0, R4
BLX _printf
MOV R0, R4
MOVS R1, #3
BLX _printf
MOV R0, R4
MOVS R1, #4
BLX _printf
MOV R0, R4
MOVS R1, #5
BLX _printf
MOV R0, R4
MOVS R1, #6
BLX _printf
MOV R0, R4
MOVS R1, #7
BLX _printf
MOV R0, R4
MOVS R1, #8
BLX _printf
MOV R0, R4
MOVS R1, #9
BLX _printf
MOVS R0, #0
POP {R4,R7,PC}
185
14. 14.
, f() :
void printing_function(int i)
{
printf ("%d\n", i);
};
186
14. 14.
; FP LR :
stp x29, x30, [sp, 32]!
; :
add x29, sp, 0
; X19 :
str x19, [sp,16]
; W19 .
; 2:
mov w19, 2
.L3:
; printing_function():
mov w0, w19
; .
add w19, w19, 1
; W0 .
bl printing_function
; ?
cmp w19, 10
; , :
bne .L3
; 0
mov w0, 0
; X19:
ldr x19, [sp,16]
; FP LR:
ldp x29, x30, [sp], 32
ret
.LC0:
.string "f(%d)\n"
14.1.5. MIPS
; IDA
; :
i = 0x10
saved_FP = 8
saved_RA = 4
; :
addiu $sp, 0x28
sw $ra, 0x28+saved_RA($sp)
sw $fp, 0x28+saved_FP($sp)
move $fp, $sp
; 2
li $v0, 2
sw $v0, 0x28+i($fp)
; . "BEQ $ZERO, $ZERO, loc_9C":
b loc_9C
or $at, $zero ; branch delay slot, NOP
#
187
14. 14.
lw $v0, 0x28+i($fp)
or $at, $zero ; NOP
slti $v0, 0xA
; 10, loc_80 ( ):
bnez $v0, loc_80
or $at, $zero ; branch delay slot, NOP
; , 0:
move $v0, $zero
; :
move $sp, $fp
lw $ra, 0x28+saved_RA($sp)
lw $fp, 0x28+saved_FP($sp)
addiu $sp, 0x28
jr $ra
or $at, $zero ; branch delay slot, NOP
B. , (BEQ).
14.1.6. -
: i, .
i, . .
, . , , :
for (i=0; i<total_entries_to_process; i++)
_;
total_entries_to_process 0, .
.
, , ,
, Keil, Xcode (LLVM),
MSVC GCC .
14.2.
4 8 , SIMD3 ,
, .. , , .
#include <stdio.h>
void my_memcpy (unsigned char* dst, unsigned char* src, size_t cnt)
{
size_t i;
for (i=0; i<cnt; i++)
dst[i]=src[i];
};
14.2.1.
; (i) 0
xor eax, eax
.L2:
; ? :
cmp rax, rdx
je .L5
3 Single instruction, multiple data
188
14. 14.
; RSI+i:
mov cl, BYTE PTR [rsi+rax]
; RDI+i:
mov BYTE PTR [rdi+rax], cl
inc rax ; i++
jmp .L2
.L5:
ret
; (i) 0
mov x3, 0
.L2:
; ? :
cmp x3, x2
beq .L5
; X1+i:
ldrb w4, [x1,x3]
; X1+i:
strb w4, [x0,x3]
add x3, x3, 1 ; i++
b .L2
.L5:
ret
PUSH {r4,lr}
; (i) 0
MOVS r3,#0
; -, :
B |L0.12|
|L0.6|
; R1+i:
LDRB r4,[r1,r3]
; R1+i:
STRB r4,[r0,r3]
; i++
ADDS r3,r3,#1
|L0.12|
; i<size?
CMP r3,r2
; ,
BCC |L0.6|
POP {r4,pc}
ENDP
Keil ARM :
189
14. 14.
; (i) 0
MOV r3,#0
|L0.4|
; ?
CMP r3,r2
; " ",
; .. R2<R3 i<size.
; R1+i:
LDRBCC r12,[r1,r3]
; R1+i:
STRBCC r12,[r0,r3]
; i++
ADDCC r3,r3,#1
; " ".
; , i<size
; , (.. i>=size)
BCC |L0.4|
;
BX lr
ENDP
14.2.3. MIPS
14.2.4.
190
14. 14.
14.3.
2 9 :
14.15: x86
mov [counter], 2 ;
jmp check
body:
;
; -
;
add [counter], 1 ;
check:
cmp [counter], 9
jle body
3 :
14.16: x86
MOV [counter], 2 ;
JMP check
body:
;
; -
;
MOV REG, [counter] ;
INC REG
MOV [counter], REG
check:
CMP [counter], 9
JLE body
, :
14.17: x86
MOV EBX, 2 ;
JMP check
body:
;
; -
; EBX, !
INC EBX ;
check:
CMP EBX, 9
JLE body
14.18: x86
MOV [counter], 2 ;
JMP label_check
label_increment:
ADD [counter], 1 ;
label_check:
CMP [counter], 10
JGE exit
;
; -
;
JMP label_increment
exit:
, ,
. , , ,
:
191
14. 14.
14.19: x86
MOV REG, 2 ;
body:
;
; -
; REG, !
INC REG ;
CMP REG, 10
JL body
LOOP. , . , ,
:
14.20: x86
; 10 1
MOV ECX, 10
body:
;
; -
; ECX, !
LOOP body
ARM. R4 :
14.21: ARM
MOV R4, 2 ;
B check
body:
;
; -
; R4, !
ADD R4,R4, #1 ;
check:
CMP R4, #10
BLT body
14.4.
14.4.1. #1
LOOP ?
14.4.2. #2
, (14.1.1 (. 178)), -
, , [6..20].
14.4.3. #3
_main PROC
push esi
push edi
mov edi, DWORD PTR __imp__printf
mov esi, 100
npad 3 ; align next label
$LL3@main:
push esi
192
14. 14.
push OFFSET $SG2795 ; '%d'
call edi
dec esi
add esp, 8
test esi, esi
jg SHORT $LL3@main
pop edi
xor eax, eax
pop esi
ret 0
_main ENDP
|L0.40|
DCB "%d\n",0
DCW 0x0000
|L0.24|
DCB "%d\n",0
193
14. 14.
.string "%d\n"
var_18 = 0x18
var_C = 0xC
var_8 = 8
var_4 = 4
: G.1.7 (. 986).
14.4.4. #4
_main PROC
push esi
push edi
mov edi, DWORD PTR __imp__printf
mov esi, 1
npad 3 ; align next label
$LL3@main:
push esi
push OFFSET $SG2795 ; '%d'
call edi
add esi, 3
add esp, 8
cmp esi, 100
jl SHORT $LL3@main
pop edi
xor eax, eax
pop esi
ret 0
_main ENDP
194
14. 14.
14.28: Keil 6/2013 ( ARM)
main PROC
PUSH {r4,lr}
MOV r4,#1
|L0.8|
MOV r1,r4
ADR r0,|L0.40|
BL __2printf
ADD r4,r4,#3
CMP r4,#0x64
MOVGE r0,#0
BLT |L0.8|
POP {r4,pc}
ENDP
|L0.40|
DCB "%d\n",0
DCW 0x0000
|L0.24|
DCB "%d\n",0
var_18 = 0x18
var_10 = 0x10
var_C = 0xC
var_8 = 8
var_4 = 4
195
14. 14.
lui $gp, (__gnu_local_gp >> 16)
addiu $sp, 0x28
la $gp, (__gnu_local_gp & 0xFFFF)
sw $ra, 0x28+var_4($sp)
sw $s2, 0x28+var_8($sp)
sw $s1, 0x28+var_C($sp)
sw $s0, 0x28+var_10($sp)
sw $gp, 0x28+var_18($sp)
la $s2, $LC0 # "%d\n"
li $s0, 1
li $s1, 0x64 # 'd'
: G.1.8 (. 987).
196
15. - 15. -
15
15.1. strlen()
. strlen()1 while(). ,
MSVC:
int my_strlen (const char * str)
{
const char *eos = str;
while( *eos++ ) ;
int main()
{
// test
return my_strlen("hello!");
};
15.1.1. x86
MSVC
, :
_eos$ = 4 ; size = 4
_str$ = 8 ; size = 4
_strlen PROC
push ebp
mov ebp, esp
push ecx
mov eax, DWORD PTR _str$[ebp] ; "str"
mov DWORD PTR _eos$[ebp], eax ; "eos"
$LN2@strlen_:
mov ecx, DWORD PTR _eos$[ebp] ; ECX=eos
197
15. - 15. -
;
: MOVSX TEST.
. MOVSX , - ,
, EDX. EDX 32-. MOVSX MOV with Sign-Extend. 8-
31- MOVSX , , , .
.
MSVC GCC char . , char, int (int
), -2 ( 0xFE) int,
0x000000FE, , int, , 254, -2. -2 int
0xFFFFFFFE. 0xFE char int
, . MOVSX.
. (30 (. 471)).
char EDX,
, DL. , . register allocator
.
TEST EDX, EDX. TEST (19 (. 316)).
EDX 0.
GCC
GCC 4.4.1:
public strlen
strlen proc near
push ebp
mov ebp, esp
sub esp, 10h
mov eax, [ebp+arg_0]
mov [ebp+eos], eax
loc_80483F0:
mov eax, [ebp+eos]
movzx eax, byte ptr [eax]
test al, al
setnz al
add [ebp+eos], 1
test al, al
jnz short loc_80483F0
mov edx, [ebp+eos]
mov eax, [ebp+arg_0]
mov ecx, edx
sub ecx, eax
mov eax, ecx
sub eax, 1
leave
retn
strlen endp
198
15. - 15. -
, , : mov al, byte ptr [eax] / test al,
al , EAX . ,
. , ,
( ) .
SETNZ. , AL , test al, al
ZF 0, SETNZ, ZF==0 (NZ not zero) 1 AL. , AL , -
loc_80483F0. , ,
.
MSVC
. ,
.
INC/ DEC -. .
199
15. - 15. -
MSVC + OllyDbg
() OllyDbg. :
. 15.1: OllyDbg:
, OllyDbg , , .
EAX, Follow in Dump , .
hello!. 1 , . OllyDbg ,
- , .
200
15. - 15. -
F8 ( , ) , :
. 15.2: OllyDbg:
, EAX .
201
15. - 15. -
F8 , :
. 15.3: OllyDbg:
, EAX , . EDX
. .
202
15. - 15. -
SUB :
EAX 7. , hello! 6, -
7. strlen() .
.
GCC
push ebp
mov ebp, esp
mov ecx, [ebp+arg_0]
mov eax, ecx
loc_8048418:
movzx edx, byte ptr [eax]
add eax, 1
test dl, dl
jnz short loc_8048418
not ecx
add eax, ecx
pop ebp
retn
strlen endp
203
15. - 15. -
. -. ECX,
str, .
. : (30 (. 471)).
, , , :
ecx=str;
eax=eos;
ecx=(ecx)1;
eax=eax+ecx
return eax
:
ecx=str;
eax=eos;
eax=eaxecx;
eax=eax1;
return eax
GCC , ? . , -
.
15.1.2. ARM
32- ARM
eos = 8
str = 4
LLVM . , -
. :
eos str. IDA var_8 var_4 eos str .
, str eos.
loc_2CB8 .
(LDR, ADD, STR) eos R0.
eos .
204
15. - 15. -
LDRSB R0, [R0] (Load Register Signed Byte) R0, -
32- (signed) R02 . MOVSX x86.
(signed), char .
(15.1.1 (. 198)) , x86.
, ARM 8- 16- , -
x86. , , x86 ,
16- 8086 8- 8080, ARM 32- RISC-. -
, ARM, 32- .
, LDRSB R0, . CMP BEQ ,
0. 0, . 0, .
eos str, ,
R0.
N.B. . R0-R3 scratch registers.
,
. , .
, .
(BX) LR.
loc_2DF6
LDRB.W R2, [R1],#1
CMP R2, #0
BNE loc_2DF6
MVNS R0, R0
ADD R0, R1
BX LR
loc_2C8
LDRB R2, [R1],#1
CMP R2, #0
SUBEQ R0, R1, R0
SUBEQ R0, R0, #1
2 Keil char , MSVC GCC.
3 (PowerPC, ARM) Branch if Not Equal
4 MoVe Not
205
15. - 15. -
BNE loc_2C8
BX LR
, , , str eos 1
, . -EQ ,
CMP . , R0 0,
SUBEQ R0.
ARM64
my_strlen:
mov x1, x0
; X1 (eos), ,
.L58:
; X1 W2, X1 (-)
ldrb w2, [x1],1
; Compare and Branch if NonZero: W0 , .L58
cbnz w2, .L58
; X0 X1
sub x0, x1, x0
; 32-
sub w0, w0, #1
ret
15.1.1 (. 199): , ,
1 . .
, : my_strlen() 32- int,
size_t 64- .
, , strlen() , 4GB,
64- 64- . - ,
SUB 32- , SUB
64- ( ). , ,
, .
my_strlen:
;
sub sp, sp, #32
; (str) [sp,8]
str x0, [sp,8]
ldr x0, [sp,8]
; "str" "eos"
str x0, [sp,24]
nop
.L62:
; eos++
ldr x0, [sp,24] ; "eos" X0
add x1, x0, 1 ; X0
str x1, [sp,24] ; X0 "eos"
; X0 W0
ldrb w0, [x0]
; ? (WZR 32- )
cmp w0, wzr
; (Branch Not Equal)
bne .L62
; . .
; "eos" X1
ldr x1, [sp,24]
; "str" X0
ldr x0, [sp,8]
;
206
15. - 15. -
sub x0, x1, x0
;
sub w0, w0, #1
;
add sp, sp, 32
ret
. ( ). :
32- .
15.1.3. MIPS
loc_4:
; "eos" $a1:
lb $a1, 0($v1)
or $at, $zero ; load delay slot, NOP
; , loc_4:
bnez $a1, loc_4
; , "eos":
addiu $v1, 1 ; branch delay slot
; . "str":
nor $v0, $zero, $a0
; $v0=str1
jr $ra
; = $v1 + $v0 = eos + ( str1 ) = eos str 1
addu $v0, $v1, $v0 ; branch delay slot
15.2.
15.2.1. #1
207
15. - 15. -
jne SHORT $LL4@f
$LN2@f:
ret 0
_f ENDP
208
15. - 15. -
csinc w2, w2, w2, ne
cbnz w1, .L3
.L2:
mov w0, w2
ret
.L4:
mov w2, w1
b .L2
G.1.9 (. 987).
209
16. 16.
16
, . , ADD
SUB : 18 .52.1.
, . LEA, ,
: A.6.2 (. 965).
16.1.
16.1.1.
8 , . , MSVC
, .
_TEXT SEGMENT
_a$ = 8 ; size = 4
_f PROC
; File c:\polygon\c\2.c
mov eax, DWORD PTR _a$[esp4]
add eax, eax
add eax, eax
add eax, eax
ret 0
_f ENDP
_TEXT ENDS
END
16.1.2.
2n .
unsigned int f(unsigned int a)
{
return a*4;
};
210
16. 16.
16.2: MSVC 2010
_a$ = 8 ; size = 4
_f PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _a$[ebp]
shl eax, 2
pop ebp
ret 0
_f ENDP
4 2 , 2 ( ).
3 100 .
:
7. 6 5 4 3 2 1 0
CF 7 6 5 4 3 2 1 0 0
.
4 ARM:
4 MIPS:
16.1.3. ,
, 7 17, .
.
32-
#include <stdint.h>
int f1(int a)
{
return a*7;
};
int f2(int a)
{
return a*28;
};
int f3(int a)
{
return a*17;
};
211
16. 16.
x86
; a*28
_a$ = 8
_f2 PROC
mov ecx, DWORD PTR _a$[esp4]
; ECX=a
lea eax, DWORD PTR [ecx*8]
; EAX=ECX*8
sub eax, ecx
; EAX=EAXECX=ECX*8ECX=ECX*7=a*7
shl eax, 2
; EAX=EAX<<2=(a*7)*4=a*28
ret 0
_f2 ENDP
; a*17
_a$ = 8
_f3 PROC
mov eax, DWORD PTR _a$[esp4]
; EAX=a
shl eax, 4
; EAX=EAX<<4=EAX*16=a*16
add eax, DWORD PTR _a$[esp4]
; EAX=EAX+a=a*16+a=a*17
ret 0
_f3 ENDP
ARM
Keil, ARM, ,
:
; a*28
||f2|| PROC
RSB r0,r0,r0,LSL #3
; R0=R0<<3R0=R0*8R0=a*8a=a*7
LSL r0,r0,#2
; R0=R0<<2=R0*4=a*7*4=a*28
BX lr
ENDP
; a*17
||f3|| PROC
ADD r0,r0,r0,LSL #4
212
16. 16.
; R0=R0+R0<<4=R0+R0*16=R0*17=a*17
BX lr
ENDP
Thumb . f2():
; a*28
||f2|| PROC
MOVS r1,#0x1c ; 28
; R1=28
MULS r0,r1,r0
; R0=R1*R0=28*a
BX lr
ENDP
; a*17
||f3|| PROC
LSLS r1,r0,#4
; R1=R0<<4=R0*16=a*16
ADDS r0,r0,r1
; R0=R0+R1=a+a*16=a*17
BX lr
ENDP
MIPS
_f2:
sll $v0, $a0, 5
; $v0 = $a0<<5 = $a0*32
sll $a0, 2
; $a0 = $a0<<2 = $a0*4
jr $ra
subu $v0, $a0 ; branch delay slot
; $v0 = $a0*32$a0*4 = $a0*28
_f3:
sll $v0, $a0, 4
; $v0 = $a0<<4 = $a0*16
jr $ra
addu $v0, $a0 ; branch delay slot
; $v0 = $a0*16+$a0 = $a0*17
64-
#include <stdint.h>
213
16. 16.
int64_t f1(int64_t a)
{
return a*7;
};
int64_t f2(int64_t a)
{
return a*28;
};
int64_t f3(int64_t a)
{
return a*17;
};
x64
; a*28
f2:
lea rax, [0+rdi*4]
; RAX=RDI*4=a*4
sal rdi, 5
; RDI=RDI<<5=RDI*32=a*32
sub rdi, rax
; RDI=RDIRAX=a*32a*4=a*28
mov rax, rdi
ret
; a*17
f3:
mov rax, rdi
sal rax, 4
; RAX=RAX<<4=a*16
add rax, rdi
; RAX=a*16+a=a*17
ret
ARM64
; a*28
f2:
lsl x1, x0, 5
; X1=X0<<5=a*32
sub x0, x1, x0, lsl 2
214
16. 16.
; X0=X1X0<<2=a*32a<<2=a*32a*4=a*28
ret
; a*17
f3:
add x0, x0, x0, lsl 4
; X0=X0+X0<<4=a+a*16=a*17
ret
16.2.
16.2.1.
, 4:
unsigned int f(unsigned int a)
{
return a/4;
};
(MSVC 2010):
7. 6 5 4 3 2 1 0
0 7 6 5 4 3 2 1 0 CF
, , 23. 23
10 (3 ). 2 .
, , - , -
!
4 ARM:
4 MIPS:
215
16. 16.
16.3.
16.3.1. #2
G.1.10 (. 987).
216
17. FPU 17. FPU
17
FPU
FPU .
CPU.
17.2. x86
FPU x86 2
Forth3 .
, ( 80486) ,
, . 4 . 80486 DX
FPU.
FWAIT, CPU , FPU
. , FPU- .. escape- (D8..DF)
, .
FPU 80- : ST(0)..ST(7). , IDA OllyDbg ST(0) ST,
Stack Top ( ).
IEEE 7545 .
17.4. /++
/++ : oat ( 6 ,
32 ) 7 double ( 8 , 64 ).
1 signicand fraction
2 wikipedia.org/wiki/Stack_machine
3 wikipedia.org/wiki/Forth_(programming_language)
4 , Doom (ru.wikipedia.org/wiki/___),
(. 390)).
8 wikipedia.org/wiki/Double-precision_oating-point_format
217
17. FPU 17. FPU
GCC long double (extended precision9 , 80 ), MSVC .
, oat , int 32- , ,
, .
17.5.
:
#include <stdio.h>
int main()
{
printf ("%f\n", f(1.2, 3.4));
};
17.5.1. x86
MSVC
MSVC 2010:
; : ST(0) = _a
; : ST(0) = _a 3.14
; :
; ST(0) = _b 4.1;
; ST(1) = _a 3.14
; : ST(0) =
pop ebp
ret 0
9 wikipedia.org/wiki/Extended_precision
218
17. FPU 17. FPU
_f ENDP
10 wikipedia.org/wiki/Forth_(programming_language)
11 wikipedia.org/wiki/Stack_machine
219
17. FPU 17. FPU
MSVC + OllyDbg
220
17. FPU 17. FPU
. FDIV , ST(0) 0,382 (quotient):
221
17. FPU 17. FPU
: FLD , ST(0) 3,4 ( 3,39999) :
222
17. FPU 17. FPU
: FMUL , ST(0) :
223
17. FPU 17. FPU
: FADDP , ST(0) , ST(1) :
GCC
push ebp
fld ds:dbl_8048608 ; 3.14
; : ST(0) = 3.14
224
17. FPU 17. FPU
; : ST(0) =
fmul [ebp+arg_8]
; : ST(0) = , ST(1) =
pop ebp
faddp st(1), st
; : ST(0) =
retn
f endp
ARM , -
. VFP (Vector Floating Point).
x86 , FPU-, , .
, D. 64- . 32 -
(double) SIMD ( ARM NEON).
32 32- S-. (oat).
: D- double-, S- single-. -
: B.3.3 (. 976).
(3,14 4,1) IEEE 754.
VLDR VMOV, , LDR MOV, D-.
, , D-, ,
SIMD (NEON), .
R-, , ,
64 , R-.
VMOV D17, R0, R1 32- R0 R1 64- D17.
225
17. FPU 17. FPU
VMOV R0, R1, D16 : D16 R0 R1,
, 64 , R0 R1.
VDIV, VMUL VADD, , , , ,
.
Thumb-2 .
f
PUSH {R3R7,LR}
MOVS R7, R2
MOVS R4, R3
MOVS R5, R0
MOVS R6, R1
LDR R2, =0x66666666 ; 4.1
LDR R3, =0x40106666
MOVS R0, R7
MOVS R1, R4
BL __aeabi_dmul
MOVS R7, R0
MOVS R4, R1
LDR R2, =0x51EB851F ; 3.14
LDR R3, =0x40091EB8
MOVS R0, R5
MOVS R1, R6
BL __aeabi_ddiv
MOVS R2, R7
MOVS R3, R4
BL __aeabi_dadd
POP {R3R7,PC}
226
17. FPU 17. FPU
; IEEE 754:
.LC25:
.word 1374389535 ; 3.14
.word 1074339512
.LC26:
.word 1717986918 ; 4.1
.word 1074816614
fmov x1, d0
; X1 = a/3.14
ldr x2, [sp]
; X2 = b
ldr x0, .LC26
; X0 = 4.1
fmov d0, x2
; D0 = b
fmov d1, x0
; D1 = 4.1
fmul d0, d0, d1
; D0 = D0*D1 = b*4.1
fmov x0, d0
; X0 = D0 = b*4.1
fmov d0, x1
; D0 = a/3.14
fmov d1, x0
; D1 = X0 = b*4.1
fadd d0, d0, d1
; D0 = D0+D1 = a/3.14 + b*4.1
fmov x0, d0 ; \
fmov d0, x0 ; /
add sp, sp, 16
ret
.LC25:
.word 1374389535 ; 3.14
.word 1074339512
.LC26:
.word 1717986918 ; 4.1
.word 1074816614
GCC . , -
( GMOV). , GCC 4.9
ARM64. ARM64 64- D- 64-.
double GPR . 32- CPU.
, , , -
FMADD.
227
17. FPU 17. FPU
17.5.6. MIPS
MIPS ( 4),
, FPU.
ARM, MIPS . 32 32- ($F0-$F31): C.1.2 (. 978).
64- double, 32- F-.
:
LWC1 32- ( 1 ). -
LWC1 L.D.
DIV.D, MUL.D, ADD.D , (.D -
, .S )
: LUI .
, 64- double $V0. .
- - , , 12 .
17.6.
#include <math.h>
#include <stdio.h>
int main ()
{
printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
return 0;
}
12 dennis(a)yurichev.com
228
17. FPU 17. FPU
17.6.1. x86
, (MSVC 2010):
_main PROC
push ebp
mov ebp, esp
sub esp, 8 ;
fld QWORD PTR __real@3ff8a3d70a3d70a4
fstp QWORD PTR [esp]
sub esp, 8 ;
fld QWORD PTR __real@40400147ae147ae1
fstp QWORD PTR [esp]
call _pow
add esp, 8 ; "" .
; 8 .
; ST(0)
_main
var_C = 0xC
PUSH {R7,LR}
MOV R7, SP
SUB SP, SP, #4
VLDR D16, =32.01
VMOV R0, R1, D16
VLDR D16, =1.54
VMOV R2, R3, D16
BLX _pow
VMOV D16, R0, R1
MOV R0, 0xFC1 ; "32.01 ^ 1.54 = %lf\n"
ADD R0, PC
VMOV R1, R2, D16
BLX _printf
MOVS R1, 0
STR R0, [SP,#0xC+var_C]
MOV R0, R1
ADD SP, SP, #4
POP {R7,PC}
13 ,
229
17. FPU 17. FPU
dbl_2F90 DCFD 32.01 ; DATA XREF: _main+6
dbl_2F98 DCFD 1.54 ; DATA XREF: _main+E
, 64- R-.
(, ), R-
D-.
, , _pow R0 R1, R2 R3. R0
R1. _pow D16, R1 R2, printf() -.
_main
STMFD SP!, {R4R6,LR}
LDR R2, =0xA3D70A4 ; y
LDR R3, =0x3FF8A3D7
LDR R0, =0xAE147AE1 ; x
LDR R1, =0x40400147
BL pow
MOV R4, R0
MOV R2, R4
MOV R3, R1
ADR R0, a32_011_54Lf ; "32.01 ^ 1.54 = %lf\n"
BL __2printf
MOV R0, #0
LDMFD SP!, {R4R6,PC}
D-, R-.
230
17. FPU 17. FPU
D0 D1: pow() . D0 pow().
printf() , printf()
X-, D-.
17.6.5. MIPS
var_10 = 0x10
var_4 = 4
; :
lui $gp, (dword_9C >> 16)
addiu $sp, 0x20
la $gp, (__gnu_local_gp & 0xFFFF)
sw $ra, 0x20+var_4($sp)
sw $gp, 0x20+var_10($sp)
lui $v0, (dword_A4 >> 16) ; ?
; 32- 32.01:
lwc1 $f12, dword_9C
; pow():
lw $t9, (pow & 0xFFFF)($gp)
; 32- 32.01:
lwc1 $f13, $LC0
lui $v0, ($LC1 >> 16) ; ?
; 32- 1.54:
lwc1 $f14, dword_A4
or $at, $zero ; load delay slot, NOP
; 32- 1.54:
lwc1 $f15, $LC1
; pow():
jalr $t9
or $at, $zero ; branch delay slot, NOP
lw $gp, 0x20+var_10($sp)
; $f0 $f1 $a3 $a2:
mfc1 $a3, $f0
lw $t9, (printf & 0xFFFF)($gp)
mfc1 $a2, $f1
; printf():
lui $a0, ($LC2 >> 16) # "32.01 ^ 1.54 = %lf\n"
jalr $t9
la $a0, ($LC2 & 0xFFFF) # "32.01 ^ 1.54 = %lf\n"
; :
lw $ra, 0x20+var_4($sp)
; 0:
move $v0, $zero
jr $ra
addiu $sp, 0x20
; 32.01:
.rodata.cst8:00000098 $LC0: .word 0x40400147 # DATA XREF: main+20
.rodata.cst8:0000009C dword_9C: .word 0xAE147AE1 # DATA XREF: main
.rodata.cst8:0000009C # main+18
; 1.54:
.rodata.cst8:000000A0 $LC1: .word 0x3FF8A3D7 # DATA XREF: main+24
.rodata.cst8:000000A0 # main+30
.rodata.cst8:000000A4 dword_A4: .word 0xA3D70A4 # DATA XREF: main+14
231
17. FPU 17. FPU
17.7.
:
#include <stdio.h>
return b;
};
int main()
{
printf ("%f\n", d_max (1.2, 3.4));
printf ("%f\n", d_max (5.6, 4));
};
, , , .
17.7.1. x86
MSVC
MSVC 2010:
; : ST(0) = _b
; _b ( ST(0)) _a,
fnstsw ax
test ah, 5
jp SHORT $LN1@d_max
; a>b
, FLD _b ST(0).
FCOMP ST(0) , _a C3/ C2/ C0 FPU.
16- FPU.
FCOMP . FCOM,
, .
232
17. FPU 17. FPU
, Intel P614 , C3/ C2/ C0. ,
( , FPU - ).
Intel P6 FCOMI/ FCOMIP/ FUCOMI/ FUCOMIP, , -
ZF/ PF/ CF.
FNSTSW AX. C3/ C2/ C0 , , 14, 10,
8. AX, AH.
b > a , C3/ C2/ C0 : 0, 0, 0.
a > b, : 0, 0, 1.
a = b, : 1, 0, 0.
( ), : 1, 1, 1.
C3/ C2/ C0 AX:
14 10 9 8
C3 C2 C1 C0
C3 C2 C1 C0
One common reason to test the parity ag actually has nothing to do with parity. The FPU has four
condition ags (C0 to C3), but they can not be tested directly, and must instead be rst copied to the ags
register. When this happens, C0 is placed in the carry ag, C2 in the parity ag and C3 in the zero ag. The
C2 ag is set when e.g. incomparable oating point values (NaN or unsupported format) are compared with
the FUCOM instructions.
Wikipedia, FPU- .
PF 1, C0 C2 1 0. JP (jump if PF==1).
C3/ C2/ C0 , , JP
: b > a a = b ( C3 test ah, 5).
. , FLD _b ST(0), ,
_a .
C2?
C2 (NaN, ..), . ,
FPU-, , .
233
17. FPU 17. FPU
OllyDbg: a=1,2 b=3,4
OllyDbg:
: a = 1, 2 b = 3, 4 ( : 2 32- ). b (3,4)
ST(0). FCOMP. OllyDbg FCOMP,
.
234
17. FPU 17. FPU
FCOMP :
235
17. FPU 17. FPU
FNSTSW :
, AX . , condition- . (OllyDbg -
FNSTSW FSTSW ).
236
17. FPU 17. FPU
TEST :
PF . : 0 0, 0 . OllyDbg -
JP JPE18 . .
237
17. FPU 17. FPU
JPE , FLD ST(0) b (3,4):
238
17. FPU 17. FPU
OllyDbg: a=5,6 b=-1
OllyDbg:
239
17. FPU 17. FPU
FCOMP :
240
17. FPU 17. FPU
FNSTSW :
, AX 0x100: C0 16- .
241
17. FPU 17. FPU
TEST :
PF . : 0x100 1, 1 . JPE .
242
17. FPU 17. FPU
JPE , FLD ST(0) a (5,6):
MSVC 2010
; : ST(0) = _a
ret 0
$LN5@d_max:
; ST(0) ST(0) ,
; _b
fstp ST(0)
; : ST(0) = _b
243
17. FPU 17. FPU
ret 0
_d_max ENDP
FCOM FCOMP , . -
, . C3/ C2/ C0 :
a > b, C3/ C2/ C0 : 0, 0, 0.
b > a, : 0, 0, 1.
a = b, : 1, 0, 0.
test ah, 65 C3 C0. , a > b:
JNE . FSTP ST(1) ST(0) -
. , ST(0) ( _a) ST(1).
_a. . ST(0) _a
.
JNE : b > a a = b. ST(0) ST(0) (
). ,
ST(1) ( _b). . FPU
, .
244
17. FPU 17. FPU
OllyDbg: a=1,2 =3,4
FLD :
245
17. FPU 17. FPU
FCOM :
C0 , .
246
17. FPU 17. FPU
FNSTSW , AX=0x3100:
247
17. FPU 17. FPU
TEST :
ZF=0, .
248
17. FPU 17. FPU
FSTP ST ( FSTP ST(0)) 1,2 , 3,4:
, FSTP ST FPU-.
249
17. FPU 17. FPU
OllyDbg: a=5,6 b=-4
FLD :
FCOM.
250
17. FPU 17. FPU
FCOM :
condition- .
251
17. FPU 17. FPU
FNSTSW , AX=0x3000:
252
17. FPU 17. FPU
TEST :
ZF=1, .
253
17. FPU 17. FPU
FSTP ST(1) : FPU- 5,6.
GCC 4.4.1
push ebp
mov ebp, esp
sub esp, 10h
; a b :
; a b FPU:
254
17. FPU 17. FPU
fld [ebp+a]
fld [ebp+b]
; : ST(0) b; ST(1) a
; : ST(0) a; ST(1) b
fucompp ; a b , .. a b
fnstsw ax ; FPU AX
sahf ; SF, ZF, AF, PF, CF AH
setnbe al ; 1 AL, CF=0 ZF=0
test al, al ; AL==0 ?
jz short loc_8048453 ;
fld [ebp+a]
jmp short locret_8048456
loc_8048453:
fld [ebp+b]
locret_8048456:
leave
retn
d_max endp
FUCOMPP FCOM, ,
-.
-.
FPU , NaN19 .
, , . .
, -
, .
, FCOM - . FUCOM
.
SAHF (Store AH into Flags) , FPU. 8 AH
8 :
7 6 4 2 0
SF ZF AF PF CF
C3 C2 C1 C0
255
17. FPU 17. FPU
AL 1, JZ _a.
, _b.
GCC 4.4.1
push ebp
mov ebp, esp
fld [ebp+arg_0] ; _a
fld [ebp+arg_8] ; _b
; ST(0) ST(0) ( ), ,
; _b
fstp st
jmp short loc_804844A
loc_8048448:
; _a ST(0), , _a
fstp st(1)
loc_804844A:
pop ebp
retn
d_max endp
, , : JA SAHF. ,
, ( JA, JAE, JBE, JBE, JE/ JZ,
JNA, JNAE, JNB, JNBE, JNE/ JNZ) CF ZF.
C3 C2 C1 C0
, AH CPU SAHF:
7 6 4 2 0
SF ZF AF PF CF
C3 C0 ZF CF ,
. JA , CF ZF .
, FNSTSW/ SAHF.
, FPU C3/ C2/ C0 , -
?
256
17. FPU 17. FPU
, FPU P6, CPU -
FPU.
:
, FXCH ( ). -
FLD FCMOVBE (below or equal ) FCMOVA (above ). ,
.
FUCOMI ST(0) (a) ST(1) (b) CPU. FCMOVBE
ST(1) ( b) ST(0) ( a) ST 0(a) <= ST 1(b). (a > b),
a ST(0).
FSTP ST(0) , ST(1).
GDB:
257
17. FPU 17. FPU
39 R2: Empty 0x00000000000000000000
40 R1: Empty 0x00000000000000000000
41 R0: Empty 0x00000000000000000000
42
43 Status Word: 0x3000
44 TOP: 6
45 Control Word: 0x037f IM DM ZM OM UM PM
46 PC: Extended Precision (64bits)
47 RC: Round to nearest
48 Tag Word: 0x0fff
49 Instruction Pointer: 0x73:0x080484a4
50 Operand Pointer: 0x7b:0xbffff118
51 Opcode: 0x0000
52 (gdb) ni
53 0x080484aa in d_max ()
54 (gdb) info float
55 R7: Valid 0x4000d999999999999800 +3.399999999999999911
56 =>R6: Valid 0x3fff9999999999999800 +1.199999999999999956
57 R5: Empty 0x00000000000000000000
58 R4: Empty 0x00000000000000000000
59 R3: Empty 0x00000000000000000000
60 R2: Empty 0x00000000000000000000
61 R1: Empty 0x00000000000000000000
62 R0: Empty 0x00000000000000000000
63
64 Status Word: 0x3000
65 TOP: 6
66 Control Word: 0x037f IM DM ZM OM UM PM
67 PC: Extended Precision (64bits)
68 RC: Round to nearest
69 Tag Word: 0x0fff
70 Instruction Pointer: 0x73:0x080484a8
71 Operand Pointer: 0x7b:0xbffff118
72 Opcode: 0x0000
73 (gdb) disas $eip
74 Dump of assembler code for function d_max:
75 0x080484a0 <+0>: fldl 0x4(%esp)
76 0x080484a4 <+4>: fldl 0xc(%esp)
77 0x080484a8 <+8>: fxch %st(1)
78 => 0x080484aa <+10>: fucomi %st(1),%st
79 0x080484ac <+12>: fcmovbe %st(1),%st
80 0x080484ae <+14>: fstp %st(1)
81 0x080484b0 <+16>: ret
82 End of assembler dump.
83 (gdb) ni
84 0x080484ac in d_max ()
85 (gdb) info registers
86 eax 0x1 1
87 ecx 0xbffff1c4 1073745468
88 edx 0x8048340 134513472
89 ebx 0xb7fbf000 1208225792
90 esp 0xbffff10c 0xbffff10c
91 ebp 0xbffff128 0xbffff128
92 esi 0x0 0
93 edi 0x0 0
94 eip 0x80484ac 0x80484ac <d_max+12>
95 eflags 0x203 [ CF IF ]
96 cs 0x73 115
97 ss 0x7b 123
98 ds 0x7b 123
99 es 0x7b 123
100 fs 0x0 0
101 gs 0x33 51
102 (gdb) ni
103 0x080484ae in d_max ()
104 (gdb) info float
105 R7: Valid 0x4000d999999999999800 +3.399999999999999911
106 =>R6: Valid 0x4000d999999999999800 +3.399999999999999911
107 R5: Empty 0x00000000000000000000
108 R4: Empty 0x00000000000000000000
258
17. FPU 17. FPU
109 R3: Empty 0x00000000000000000000
110 R2: Empty 0x00000000000000000000
111 R1: Empty 0x00000000000000000000
112 R0: Empty 0x00000000000000000000
113
114 Status Word: 0x3000
115 TOP: 6
116 Control Word: 0x037f IM DM ZM OM UM PM
117 PC: Extended Precision (64bits)
118 RC: Round to nearest
119 Tag Word: 0x0fff
120 Instruction Pointer: 0x73:0x080484ac
121 Operand Pointer: 0x7b:0xbffff118
122 Opcode: 0x0000
123 (gdb) disas $eip
124 Dump of assembler code for function d_max:
125 0x080484a0 <+0>: fldl 0x4(%esp)
126 0x080484a4 <+4>: fldl 0xc(%esp)
127 0x080484a8 <+8>: fxch %st(1)
128 0x080484aa <+10>: fucomi %st(1),%st
129 0x080484ac <+12>: fcmovbe %st(1),%st
130 => 0x080484ae <+14>: fstp %st(1)
131 0x080484b0 <+16>: ret
132 End of assembler dump.
133 (gdb) ni
134 0x080484b0 in d_max ()
135 (gdb) info float
136 =>R7: Valid 0x4000d999999999999800 +3.399999999999999911
137 R6: Empty 0x4000d999999999999800
138 R5: Empty 0x00000000000000000000
139 R4: Empty 0x00000000000000000000
140 R3: Empty 0x00000000000000000000
141 R2: Empty 0x00000000000000000000
142 R1: Empty 0x00000000000000000000
143 R0: Empty 0x00000000000000000000
144
145 Status Word: 0x3800
146 TOP: 7
147 Control Word: 0x037f IM DM ZM OM UM PM
148 PC: Extended Precision (64bits)
149 RC: Round to nearest
150 Tag Word: 0x3fff
151 Instruction Pointer: 0x73:0x080484ae
152 Operand Pointer: 0x7b:0xbffff118
153 Opcode: 0x0000
154 (gdb) quit
155 A debugging session is active.
156
157 Inferior 1 [process 30194] will be killed.
158
159 Quit anyway? (y or n) y
160 dennis@ubuntuvm:~/polygon$
ni, FLD .
FPU ( 33).
, FPU , (17.5.1 (. 224)). GDB
STx, FPU (Rx). ( 35) .
TOP Status Word ( 44). 6,
6.
a b FXCH ( 54).
FUCOMI ( 83). : CF ( 95).
FCMOVBE b (. 104).
FSTP ( 136). TOP 7, FPU- -
7.
259
17. FPU 17. FPU
17.7.2. ARM
, , . ,
ARM .
Thumb . 16- 4 ,
.
Thumb-2 Thumb- .
, IDA, VMOVGT, .
VMOV, IDA -GT ,
IT GT.
IT if-then block. -
, . IT GT ,
, GT (Greater Than) .
. , Angry Birds ( iOS):
260
17. FPU 17. FPU
ITE if-then-else . ,
, ITE (NE, not equal) , .
( NE EQ (equal)).
VMOV ( VMOEQ) , (BLX).
, Angry Birds:
T , -
. IDA -EQ.
, , ITEEE EQ (if-then-else-else-else),
:
EQ
NE
NE
NE
Angry Birds:
, Thumb-2 , , -
IT , .
261
17. FPU 17. FPU
VMOV D17, R0, R1
VSTR D17, [SP,#0x20+a]
VSTR D16, [SP,#0x20+b]
VLDR D16, [SP,#0x20+a]
VLDR D17, [SP,#0x20+b]
VCMPE.F64 D16, D17
VMRS APSR_nzcv, FPSCR
BLE loc_2E08
VLDR D16, [SP,#0x20+a]
VSTR D16, [SP,#0x20+val_to_return]
B loc_2E10
loc_2E08
VLDR D16, [SP,#0x20+b]
VSTR D16, [SP,#0x20+val_to_return]
loc_2E10
VLDR D16, [SP,#0x20+val_to_return]
VMOV R0, R1, D16
MOV SP, R7
LDR R7, [SP+0x20+b],#4
BX LR
, , - a b, ,
.
loc_1C0
MOVS R0, R4
MOVS R1, R5
POP {R3R7,PC}
Keil FPU-, , , -
. __aeabi_cdrcmple.
17.7.3. ARM64
d_max:
; D0 a, D1 b
fcmpe d0, d1
fcsel d0, d0, d1, gt
; D0
ret
262
17. FPU 17. FPU
FCSEL (Floating Conditional Select) D0 D1 D0 (GT Greater Than
), , APSR FPSCR. ,
, .
(GT), D0 D0 (.. ). ,
D1 D0.
d_max:
; "Register Save Area"
sub sp, sp, #16
str d0, [sp,8]
str d1, [sp]
;
ldr x1, [sp,8]
ldr x0, [sp]
fmov d0, x1
fmov d1, x0
; D0 a, D1 b
fcmpe d0, d1
ble .L76
; a>b; D0 (a) X0
ldr x0, [sp,8]
b .L74
.L76:
; a<=b; D1 (b) X0
ldr x0, [sp]
.L74:
; X0
fmov d0, x0
; D0
add sp, sp, 16
ret
GCC .
(Register Save Area). X0/ X1 D0/ D1 -
FCMPE. , . FCMPE
APSR. FCSEL,
: BLE (Branch if Less than or Equal (
)). (a > b) a X0. (a <= b) b X0.
, X0 D0, .
, ,
( FCSEL).
. oat double.
float f_max (float a, float b)
{
if (a>b)
return a;
return b;
};
f_max:
; S0 a, S1 b
fcmpe s0, s1
fcsel s0, s0, s1, gt
; S0
263
17. FPU 17. FPU
ret
17.7.4. MIPS
MIPS , FPU -
CPU. MIPS ( FCC0), 8 ( FCC7-FCC0).
FCCR.
locret_14:
jr $ra
or $at, $zero ; branch delay slot, NOP
17.8. ,
, 24 .
12 34 12, 34, .
, .
17.9. x64
, x86-64, : 27 (. 451).
17.10.
17.10.1. #1
17.10.2. #2
?
24 ru.wikipedia.org/wiki/__
264
17. FPU 17. FPU
17.24: MSVC 2010
__real@4014000000000000 DQ 04014000000000000r ; 5
_a1$ = 8 ; size = 8
_a2$ = 16 ; size = 8
_a3$ = 24 ; size = 8
_a4$ = 32 ; size = 8
_a5$ = 40 ; size = 8
_f PROC
fld QWORD PTR _a1$[esp4]
fadd QWORD PTR _a2$[esp4]
fadd QWORD PTR _a3$[esp4]
fadd QWORD PTR _a4$[esp4]
fadd QWORD PTR _a5$[esp4]
fdiv QWORD PTR __real@4014000000000000
ret 0
_f ENDP
arg_10 = 0x10
arg_14 = 0x14
arg_18 = 0x18
arg_1C = 0x1C
arg_20 = 0x20
arg_24 = 0x24
265
17. FPU 17. FPU
jr $ra
div.d $f0, $f2
G.1.11 (. 987).
266
18. 18.
18
, 1 .
18.1.
#include <stdio.h>
int main()
{
int a[20];
int i;
return 0;
};
18.1.1. x86
MSVC
267
18. 18.
mov DWORD PTR _a$[ebp+edx*4], ecx
jmp SHORT $LN5@main
$LN4@main:
mov DWORD PTR _i$[ebp], 0
jmp SHORT $LN3@main
$LN2@main:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
$LN3@main:
cmp DWORD PTR _i$[ebp], 20 ; 00000014H
jge SHORT $LN1@main
mov ecx, DWORD PTR _i$[ebp]
mov edx, DWORD PTR _a$[ebp+ecx*4]
push edx
mov eax, DWORD PTR _i$[ebp]
push eax
push OFFSET $SG2463
call _printf
add esp, 12 ; 0000000cH
jmp SHORT $LN2@main
$LN1@main:
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
, . , . shl ecx, 1
ECX 2, (16.2.1 (. 215)).
80 , 20 4 .
268
18. 18.
OllyDbg.
, : 32- int, 2:
. 18.1: OllyDbg:
, 20 .
GCC
GCC 4.4.1:
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 70h
mov [esp+70h+i], 0 ; i=0
jmp short loc_804840A
loc_80483F7:
mov eax, [esp+70h+i]
mov edx, [esp+70h+i]
add edx, edx ; edx=i*2
269
18. 18.
mov [esp+eax*4+70h+i_2], edx
add [esp+70h+i], 1 ; i++
loc_804840A:
cmp [esp+70h+i], 13h
jle short loc_80483F7
mov [esp+70h+i], 0
jmp short loc_8048441
loc_804841B:
mov eax, [esp+70h+i]
mov edx, [esp+eax*4+70h+i_2]
mov eax, offset aADD ; "a[%d]=%d\n"
mov [esp+70h+var_68], edx
mov edx, [esp+70h+i]
mov [esp+70h+var_6C], edx
mov [esp+70h+var_70], eax
call _printf
add [esp+70h+i], 1
loc_8048441:
cmp [esp+70h+i], 13h
jle short loc_804841B
mov eax, 0
leave
retn
main endp
a int* ( int).
, , ( -
). a[idx], idx
, , .
. string . const char[]. -
. : string[i]
/++!
18.1.2. ARM
EXPORT _main
_main
STMFD SP!, {R4,LR}
SUB SP, SP, #0x50 ; 20- int
MOV R4, #0 ; i
B loc_4A0
loc_494
MOV R0, R4,LSL#1 ; R0=R4*2
STR R0, [SP,R4,LSL#2] ; R0 SP+R4<<2 ( SP+R4*4)
ADD R4, R4, #1 ; i=i+1
loc_4A0
CMP R4, #20 ; i<20?
BLT loc_494 ; ,
MOV R4, #0 ; i
B loc_4C4
loc_4B0
LDR R2, [SP,R4,LSL#2] ; ( printf) R2=*(SP+R4<<4) ( *(SP+R4*4))
MOV R1, R4 ; ( printf) R1=i
ADR R0, aADD ; "a[%d]=%d\n"
BL __2printf
270
18. 18.
ADD R4, R4, #1 ; i=i+1
loc_4C4
CMP R4, #20 ; i<20?
BLT loc_4B0 ; ,
MOV R0, #0 ;
ADD SP, SP, #0x50 ; , 20
LDMFD SP!, {R4,PC}
_main
PUSH {R4,R5,LR}
; 20 int +
SUB SP, SP, #0x54
MOVS R0, #0 ; i
MOV R5, SP ;
loc_1CE
LSLS R1, R0, #1 ; R1=i<<1 ( i*2)
LSLS R2, R0, #2 ; R2=i<<2 ( i*4)
ADDS R0, R0, #1 ; i=i+1
CMP R0, #20 ; i<20?
STR R1, [R5,R2] ; R1 *(R5+R2) ( R5+i*4)
BLT loc_1CE ; , i<20,
271
18. 18.
18.3: GCC 4.9.1 (ARM64)
.LC0:
.string "a[%d]=%d\n"
main:
; FP LR :
stp x29, x30, [sp, 112]!
; (FP=SP)
add x29, sp, 0
; 0 (WZR ):
str wzr, [x29,108]
; :
b .L2
.L3:
; "i":
ldr w0, [x29,108]
; 2:
lsl w2, w0, 1
; :
add x0, x29, 24
; 32- 64- :
ldrsw x1, [x29,108]
; (X0+X1<<2=array address+i*4) W2 (i*2) :
str w2, [x0,x1,lsl 2]
; (i):
ldr w0, [x29,108]
add w0, w0, 1
str w0, [x29,108]
.L2:
; , :
ldr w0, [x29,108]
cmp w0, 19
; L3 ( ), :
ble .L3
; .
; 0.
; ,
; (i) .
str wzr, [x29,108]
b .L4
.L5:
; :
add x0, x29, 24
; "i":
ldrsw x1, [x29,108]
; (X0+X1<<2 = + i*4)
ldr w2, [x0,x1,lsl 2]
; "a[%d]=%d\n" :
adrp x0, .LC0
add x0, x0, :lo12:.LC0
; "i" W1 printf() :
ldr w1, [x29,108]
; W2 .
; printf():
bl printf
; "i":
ldr w0, [x29,108]
add w0, w0, 1
str w0, [x29,108]
.L4:
; ?
ldr w0, [x29,108]
cmp w0, 19
; , :
ble .L5
; 0
mov w0, 0
; FP LR:
ldp x29, x30, [sp], 112
ret
272
18. 18.
18.1.3. MIPS
S-, . -
.
18.4: GCC 4.4.5 (IDA)
main:
var_70 = 0x70
var_68 = 0x68
var_14 = 0x14
var_10 = 0x10
var_C = 0xC
var_8 = 8
var_4 = 4
; :
lui $gp, (__gnu_local_gp >> 16)
addiu $sp, 0x80
la $gp, (__gnu_local_gp & 0xFFFF)
sw $ra, 0x80+var_4($sp)
sw $s3, 0x80+var_8($sp)
sw $s2, 0x80+var_C($sp)
sw $s1, 0x80+var_10($sp)
sw $s0, 0x80+var_14($sp)
sw $gp, 0x80+var_70($sp)
addiu $s1, $sp, 0x80+var_68
move $v1, $s1
move $v0, $zero
; .
; GCC :
li $a0, 0x28 # '('
273
18. 18.
addiu $sp, 0x80
: i, i 2 (
2 ) ( 4 ).
: ( $V0) 2 , ( $V1) 4.
printf(). i , ,
1 ( $S0), ( $S1) 4 .
, : 39 (. 500). ,
.
18.2.
18.2.1.
, []. ,
printf() , ? 20 ?
/++, , , .
, :
#include <stdio.h>
int main()
{
int a[20];
int i;
return 0;
};
(MSVC 2008):
_i$ = 84 ; size = 4
_a$ = 80 ; size = 80
_main PROC
push ebp
mov ebp, esp
sub esp, 84
mov DWORD PTR _i$[ebp], 0
jmp SHORT $LN3@main
$LN2@main:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
$LN3@main:
cmp DWORD PTR _i$[ebp], 20
jge SHORT $LN1@main
mov ecx, DWORD PTR _i$[ebp]
shl ecx, 1
mov edx, DWORD PTR _i$[ebp]
mov DWORD PTR _a$[ebp+edx*4], ecx
jmp SHORT $LN2@main
$LN1@main:
mov eax, DWORD PTR _a$[ebp+80]
push eax
push OFFSET $SG2474 ; 'a[20]=%d'
274
18. 18.
call DWORD PTR __imp__printf
add esp, 8
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
. 18.2: OllyDbg:
-, , 80 .
275
18. 18.
OllyDbg, . , -
:
? , EBP.
276
18. 18.
, , :
, ? - ,
, 3 ,
.
18.2.2.
, - , ?
:
#include <stdio.h>
int main()
{
int a[20];
int i;
return 0;
};
MSVC
:
3 Java, Python, ..
277
18. 18.
18.6: MSVC 2008
_TEXT SEGMENT
_i$ = 84 ; size = 4
_a$ = 80 ; size = 80
_main PROC
push ebp
mov ebp, esp
sub esp, 84
mov DWORD PTR _i$[ebp], 0
jmp SHORT $LN3@main
$LN2@main:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
$LN3@main:
cmp DWORD PTR _i$[ebp], 30 ; 0000001eH
jge SHORT $LN1@main
mov ecx, DWORD PTR _i$[ebp]
mov edx, DWORD PTR _i$[ebp] ; . .
mov DWORD PTR _a$[ebp+ecx*4], edx ; ECX.
jmp SHORT $LN2@main
$LN1@main:
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
, . . , .
278
18. 18.
OllyDbg, 30 :
279
18. 18.
:
, .
EIP 0x15. , win32-! - , ,
. , EBP 0x14, ECX EDX 0x1D.
.
main(), EBP.
i 84 . (20+1)*sizeof(int). ESP _i
PUSH -, - _i.
main():
ESP 4 i
ESP+4 80 a[20]
ESP+84 EBP
ESP+88
a[19]=_ int ( !)
a[20]=_ _ EBP.
. 20-
20. , , EBP (20 -
0x14 ). RET,
POP EIP.
RET ( - CRT), main()),
21 , 0x15 . 0x15,
, .
280
18. 18.
! buffer overow 4 .
int ( char), , ,
, , ,
. , , 5 .
GCC
GCC 4.4.1. :
public main
main proc near
push ebp
mov ebp, esp
sub esp, 60h ; 96
mov [ebp+i], 0
jmp short loc_80483D1
loc_80483C3:
mov eax, [ebp+i]
mov edx, [ebp+i]
mov [ebp+eax*4+a], edx
add [ebp+i], 1
loc_80483D1:
cmp [ebp+i], 1Dh
jle short loc_80483C3
mov eax, 0
leave
retn
main endp
, win32, .
4 wikipedia
5 : [One96]
281
18. 18.
18.3.
/++. MSVC
6 :
/RTCs Stack Frame runtime checking
/GZ Enable stack checks (/RTCs)
. ,
RET, ( ). , , .
7 , 8 .
, , .
, .
(18.1 (. 267)) MSVC RTC1 RTCs,
@_RTC_CheckStackVars@8, .
, GCC. alloca() (5.2.4 (. 28)):
#ifdef __GNUC__
#include <alloca.h> // GCC
#else
#include <malloc.h> // MSVC
#endif
#include <stdio.h>
void f()
{
char *buf=(char*)alloca (600);
#ifdef __GNUC__
snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3); // GCC
#else
_snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3); // MSVC
#endif
puts (buf);
};
, , GCC 4.7.3 :
282
18. 18.
jne .L5
mov ebx, DWORD PTR [ebp4]
leave
ret
.L5:
call __stack_chk_fail
gs:20. , , ,
gs:20. , __stack_chk_fail
- (Ubuntu 13.04 x86):
*** buffer overflow detected ***: ./2_1 terminated
======= Backtrace: =========
/lib/i386linuxgnu/libc.so.6(__fortify_fail+0x63)[0xb7699bc3]
/lib/i386linuxgnu/libc.so.6(+0x10593a)[0xb769893a]
/lib/i386linuxgnu/libc.so.6(+0x105008)[0xb7698008]
/lib/i386linuxgnu/libc.so.6(_IO_default_xsputn+0x8c)[0xb7606e5c]
/lib/i386linuxgnu/libc.so.6(_IO_vfprintf+0x165)[0xb75d7a45]
/lib/i386linuxgnu/libc.so.6(__vsprintf_chk+0xc9)[0xb76980d9]
/lib/i386linuxgnu/libc.so.6(__sprintf_chk+0x2f)[0xb7697fef]
./2_1[0x8048404]
/lib/i386linuxgnu/libc.so.6(__libc_start_main+0xf5)[0xb75ac935]
======= Memory map: ========
0804800008049000 rxp 00000000 08:01 2097586 /home/dennis/2_1
080490000804a000 rp 00000000 08:01 2097586 /home/dennis/2_1
0804a0000804b000 rwp 00001000 08:01 2097586 /home/dennis/2_1
094d1000094f2000 rwp 00000000 00:00 0 [heap]
b7560000b757b000 rxp 00000000 08:01 1048602 /lib/i386linuxgnu/libgcc_s.so.1
b757b000b757c000 rp 0001a000 08:01 1048602 /lib/i386linuxgnu/libgcc_s.so.1
b757c000b757d000 rwp 0001b000 08:01 1048602 /lib/i386linuxgnu/libgcc_s.so.1
b7592000b7593000 rwp 00000000 00:00 0
b7593000b7740000 rxp 00000000 08:01 1050781 /lib/i386linuxgnu/libc2.17.so
b7740000b7742000 rp 001ad000 08:01 1050781 /lib/i386linuxgnu/libc2.17.so
b7742000b7743000 rwp 001af000 08:01 1050781 /lib/i386linuxgnu/libc2.17.so
b7743000b7746000 rwp 00000000 00:00 0
b775a000b775d000 rwp 00000000 00:00 0
b775d000b775e000 rxp 00000000 00:00 0 [vdso]
b775e000b777e000 rxp 00000000 08:01 1050794 /lib/i386linuxgnu/ld2.17.so
b777e000b777f000 rp 0001f000 08:01 1050794 /lib/i386linuxgnu/ld2.17.so
b777f000b7780000 rwp 00020000 08:01 1050794 /lib/i386linuxgnu/ld2.17.so
bff35000bff56000 rwp 00000000 00:00 0 [stack]
Aborted (core dumped)
gs . MS-DOS DOS-.
. , Linux gs TLS (65 (. 697))
, . , win32 -
fs, TIB9 10 .
Linux ( , 3.11): arch/x86/include/asm/st
.
var_64 = 0x64
var_60 = 0x60
var_5C = 0x5C
var_58 = 0x58
var_54 = 0x54
var_50 = 0x50
var_4C = 0x4C
var_48 = 0x48
var_44 = 0x44
9 Thread Information Block
10 wikipedia.org/wiki/Win32_Thread_Information_Block
283
18. 18.
var_40 = 0x40
var_3C = 0x3C
var_38 = 0x38
var_34 = 0x34
var_30 = 0x30
var_2C = 0x2C
var_28 = 0x28
var_24 = 0x24
var_20 = 0x20
var_1C = 0x1C
var_18 = 0x18
canary = 0x14
var_10 = 0x10
PUSH {R4R7,LR}
ADD R7, SP, #0xC
STR.W R8, [SP,#0xC+var_10]!
SUB SP, SP, #0x54
MOVW R0, #aObjc_methtype ; "objc_methtype"
MOVS R2, #0
MOVT.W R0, #0
MOVS R5, #0
ADD R0, PC
LDR.W R8, [R0]
LDR.W R0, [R8]
STR R0, [SP,#0x64+canary]
MOVS R0, #2
STR R2, [SP,#0x64+var_64]
STR R0, [SP,#0x64+var_60]
MOVS R0, #4
STR R0, [SP,#0x64+var_5C]
MOVS R0, #6
STR R0, [SP,#0x64+var_58]
MOVS R0, #8
STR R0, [SP,#0x64+var_54]
MOVS R0, #0xA
STR R0, [SP,#0x64+var_50]
MOVS R0, #0xC
STR R0, [SP,#0x64+var_4C]
MOVS R0, #0xE
STR R0, [SP,#0x64+var_48]
MOVS R0, #0x10
STR R0, [SP,#0x64+var_44]
MOVS R0, #0x12
STR R0, [SP,#0x64+var_40]
MOVS R0, #0x14
STR R0, [SP,#0x64+var_3C]
MOVS R0, #0x16
STR R0, [SP,#0x64+var_38]
MOVS R0, #0x18
STR R0, [SP,#0x64+var_34]
MOVS R0, #0x1A
STR R0, [SP,#0x64+var_30]
MOVS R0, #0x1C
STR R0, [SP,#0x64+var_2C]
MOVS R0, #0x1E
STR R0, [SP,#0x64+var_28]
MOVS R0, #0x20
STR R0, [SP,#0x64+var_24]
MOVS R0, #0x22
STR R0, [SP,#0x64+var_20]
MOVS R0, #0x24
STR R0, [SP,#0x64+var_1C]
MOVS R0, #0x26
STR R0, [SP,#0x64+var_18]
MOV R4, 0xFDA ; "a[%d]=%d\n"
MOV R0, SP
ADDS R6, R0, #4
ADD R4, PC
B loc_2F1C
284
18. 18.
loc_2F14
ADDS R0, R5, #1
LDR.W R2, [R6,R5,LSL#2]
MOV R5, R0
loc_2F1C
MOV R0, R4
MOV R1, R5
BLX _printf
CMP R5, #0x13
BNE loc_2F14
LDR.W R0, [R8]
LDR R1, [SP,#0x64+canary]
CMP R0, R1
ITTTT EQ ; ?
MOVEQ R0, #0
ADDEQ SP, SP, #0x54
LDREQ.W R8, [SP+0x64+var_64],#4
POPEQ {R4R7,PC}
BLX ___stack_chk_fail
-, LLVM , ,
LLVM . , ARM
.
, -
R8. , ITTTT EQ. 0 R0,
. ,
___stack_chk_fail, , , .
18.4.
, /++ - :
void f(int size)
{
int a[size];
...
};
, ,
, , .
, , , malloc(),
, .
C99 [ISO07, . 6.7.5/2], alloca() (5.2.4 (. 28)).
, . ++
.
18.5.
.
18.8:
#include <stdio.h>
285
18. 18.
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
// 0..11
const char* get_month1 (int month)
{
return month1[month];
};
18.5.1. x64
month$ = 8
get_month1 PROC
movsxd rax, ecx
lea rcx, OFFSET FLAT:month1
mov rax, QWORD PTR [rcx+rax*8]
ret 0
get_month1 ENDP
:
MOVSXD 32- ECX ( :month) RAX -
( month int). ,
64- . ,
64-11 .
RCX.
11 , month ( -
: 52 (. 614)) . , int
. .
286
18. 18.
, (month) 8 . : 64-
( ) 64 ( 8 ). ,
8 .
month 8 . , MOV.
. 1, , February, ..
GCC 4.9 12 :
32-bit MSVC
32- MSVC:
64- , .
4, 32 4 .
ARM ARM
|L0.100|
DCD ||.data||
DCB "January",0
DCB "February",0
DCB "March",0
DCB "April",0
DCB "May",0
DCB "June",0
DCB "July",0
DCB "August",0
DCB "September",0
DCB "October",0
DCB "November",0
DCB "December",0
287
18. 18.
DCD ||.conststring||+0x26
DCD ||.conststring||+0x2b
DCD ||.conststring||+0x32
DCD ||.conststring||+0x3c
DCD ||.conststring||+0x44
DCD ||.conststring||+0x4d
R1. , LDR.
month 2 ( 4), R1 (
) . 32- R0
.
ARM Thumb
, , , LDR, LSL:
get_month1 PROC
LSLS r0,r0,#2
LDR r1,|L0.64|
LDR r0,[r1,r0]
BX lr
ENDP
18.5.3. ARM64
.LANCHOR0 = . + 0
.type month1, %object
.size month1, 96
month1:
.xword .LC2
.xword .LC3
.xword .LC4
.xword .LC5
.xword .LC6
.xword .LC7
.xword .LC8
.xword .LC9
.xword .LC10
.xword .LC11
.xword .LC12
.xword .LC13
.LC2:
.string "January"
.LC3:
.string "February"
.LC4:
.string "March"
.LC5:
.string "April"
.LC6:
.string "May"
.LC7:
.string "June"
.LC8:
.string "July"
.LC9:
.string "August"
.LC10:
.string "September"
288
18. 18.
.LC11:
.string "October"
.LC12:
.string "November"
.LC13:
.string "December"
X1 ADRP/ ADD. -
LDR, W0 (, month), 3
( 8), , ( , sxtw)
X0. 64- X0.
18.5.4. MIPS
.data # .data.rel.local
.globl month1
month1: .word aJanuary # "January"
.word aFebruary # "February"
.word aMarch # "March"
.word aApril # "April"
.word aMay # "May"
.word aJune # "June"
.word aJuly # "July"
.word aAugust # "August"
.word aSeptember # "September"
.word aOctober # "October"
.word aNovember # "November"
.word aDecember # "December"
.data # .rodata.str1.4
aJanuary: .ascii "January"<0>
aFebruary: .ascii "February"<0>
aMarch: .ascii "March"<0>
aApril: .ascii "April"<0>
aMay: .ascii "May"<0>
aJune: .ascii "June"<0>
aJuly: .ascii "July"<0>
aAugust: .ascii "August"<0>
aSeptember: .ascii "September"<0>
aOctober: .ascii "October"<0>
aNovember: .ascii "November"<0>
aDecember: .ascii "December"<0>
18.5.5.
0..11, , 12?
. - , , . ,
- , , .
MSVC win64 IDA ,
:
289
18. 18.
18.15: IDA
off_140011000 dq offset aJanuary_1 ; DATA XREF: .text:0000000140001003
; "January"
dq offset aFebruary_1 ; "February"
dq offset aMarch_1 ; "March"
dq offset aApril_1 ; "April"
dq offset aMay_1 ; "May"
dq offset aJune_1 ; "June"
dq offset aJuly_1 ; "July"
dq offset aAugust_1 ; "August"
dq offset aSeptember_1 ; "September"
dq offset aOctober_1 ; "October"
dq offset aNovember_1 ; "November"
dq offset aDecember_1 ; "December"
aJanuary_1 db 'January',0 ; DATA XREF: sub_140001020+4
; .data:off_140011000
aFebruary_1 db 'February',0 ; DATA XREF: .data:0000000140011008
align 4
aMarch_1 db 'March',0 ; DATA XREF: .data:0000000140011010
align 4
aApril_1 db 'April',0 ; DATA XREF: .data:0000000140011018
. - , (
) . ,
, , .
12 ? 13- . , CPU
64- :
18.16: IDA
off_140011000 dq offset qword_140011060
; DATA XREF: .text:0000000140001003
dq offset aFebruary_1 ; "February"
dq offset aMarch_1 ; "March"
dq offset aApril_1 ; "April"
dq offset aMay_1 ; "May"
dq offset aJune_1 ; "June"
dq offset aJuly_1 ; "July"
dq offset aAugust_1 ; "August"
dq offset aSeptember_1 ; "September"
dq offset aOctober_1 ; "October"
dq offset aNovember_1 ; "November"
dq offset aDecember_1 ; "December"
qword_140011060 dq 797261756E614Ah ; DATA XREF: sub_140001020+4
; .data:off_140011000
aFebruary_1 db 'February',0 ; DATA XREF: .data:0000000140011008
align 4
aMarch_1 db 'March',0 ; DATA XREF: .data:0000000140011010
0x797261756E614A. , - (, ) -
, -. ,
.
- ,
, ,
11. fail early and fail loudly fail-fast,
. /++ assert().
, :
18.17: assert()
const char* get_month1_checked (int month)
290
18. 18.
{
assert (month<12);
return month1[month];
};
false.
month$ = 48
get_month1_checked PROC
$LN5:
push rbx
sub rsp, 32
movsxd rbx, ecx
cmp ebx, 12
jl SHORT $LN3@get_month1
lea rdx, OFFSET FLAT:$SG3143
lea rcx, OFFSET FLAT:$SG3144
mov r8d, 29
call _wassert
$LN3@get_month1:
lea rcx, OFFSET FLAT:month1
mov rax, QWORD PTR [rcx+rbx*8]
add rsp, 32
pop rbx
ret 0
get_month1_checked ENDP
, assert() , .
, . ,
UTF-16. ( 29).
, , . GCC:
get_month1_checked:
cmp edi, 11
jg .L6
movsx rdi, edi
mov rax, QWORD PTR month1[0+rdi*8]
ret
.L6:
push rax
mov ecx, OFFSET FLAT:__PRETTY_FUNCTION__.2423
mov edx, 29
mov esi, OFFSET FLAT:.LC1
mov edi, OFFSET FLAT:.LC2
call __assert_fail
__PRETTY_FUNCTION__.2423:
.string "get_month1_checked"
GCC , .
. , -
assert() . , , MSVC
, .
291
18. 18.
Microsoft Windows NT checked free13 .
( checked), ( free, .. ).
18.6.
. ,
. .
, 3x4 12 :
0 [0][0]
1 [0][1]
2 [0][2]
3 [0][3]
4 [1][0]
5 [1][1]
6 [1][2]
7 [1][3]
8 [2][0]
9 [2][1]
10 [2][2]
11 [2][3]
18.1:
3*4:
0 1 2 3
4 5 6 7
8 9 10 11
18.2:
, () 4 ( ),
(). row-major order,
/++ Python. row-major order - :
, , .
column-major order ( )
FORTRAN, MATLAB R. column-major order - :
, , .
? -, ,
. ,
row-major order , .
18.6.1.
char. , .
0..3:
18.20:
#include <stdio.h>
char a[3][4];
13 msdn.microsoft.com/en-us/library/windows/hardware/ff543450(v=vs.85).aspx
292
18. 18.
int main()
{
int x, y;
//
for (x=0; x<3; x++)
for (y=0; y<4; y++)
a[x][y]=0;
// 0..3:
for (y=0; y<4; y++)
a[1][y]=y;
};
. , 0, 1, 2 3:
. 18.7: OllyDbg:
0..2:
18.21:
#include <stdio.h>
char a[3][4];
int main()
{
int x, y;
//
for (x=0; x<3; x++)
for (y=0; y<4; y++)
a[x][y]=0;
// 0..2:
for (x=0; x<3; x++)
a[x][2]=x;
};
. , , , 0, 1 2.
. 18.8: OllyDbg:
18.6.2.
, ,
:
293
18. 18.
#include <stdio.h>
char a[3][4];
int main()
{
a[2][3]=123;
printf ("%d\n", get_by_coordinates1(a, 2, 3));
printf ("%d\n", get_by_coordinates2(a, 2, 3));
printf ("%d\n", get_by_coordinates3(a, 2, 3));
};
: .
MSVC 2013 !
array$ = 8
a$ = 16
b$ = 24
get_by_coordinates2 PROC
movsxd rax, r8d
movsxd r9, edx
add rax, rcx
movzx eax, BYTE PTR [rax+r9*4]
ret 0
get_by_coordinates2 ENDP
array$ = 8
a$ = 16
b$ = 24
294
18. 18.
get_by_coordinates1 PROC
movsxd rax, r8d
movsxd r9, edx
add rax, rcx
movzx eax, BYTE PTR [rax+r9*4]
ret 0
get_by_coordinates1 ENDP
GCC :
get_by_coordinates1:
; 32- "a" "b" 64-
movsx rsi, esi
movsx rdx, edx
lea rax, [rdi+rsi*4]
; RAX=RDI+RSI*4= +a*4
movzx eax, BYTE PTR [rax+rdx]
; AL= RAX+RDX= +a*4+b
ret
get_by_coordinates2:
lea eax, [rdx+rsi*4]
; RAX=RDX+RSI*4=b+a*4
cdqe
movzx eax, BYTE PTR [rdi+rax]
; AL= RDI+RAX= +b+a*4
ret
get_by_coordinates3:
sal esi, 2
; ESI=a<<2=a*4
; 32- "a*4" "b" 64-
movsx rdx, edx
movsx rsi, esi
add rdi, rsi
; RDI=RDI+RSI= +a*4
movzx eax, BYTE PTR [rdi+rdx]
; AL= RDI+RDX= +a*4+b
ret
18.6.3.
. int: 4
.
:
18.24:
#include <stdio.h>
int a[10][20][30];
x86
(MSVC 2010):
295
18. 18.
18.25: MSVC 2010
_DATA SEGMENT
COMM _a:DWORD:01770H
_DATA ENDS
PUBLIC _insert
_TEXT SEGMENT
_x$ = 8 ; size = 4
_y$ = 12 ; size = 4
_z$ = 16 ; size = 4
_value$ = 20 ; size = 4
_insert PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _x$[ebp]
imul eax, 2400 ; eax=600*4*x
mov ecx, DWORD PTR _y$[ebp]
imul ecx, 120 ; ecx=30*4*y
lea edx, DWORD PTR _a[eax+ecx] ; edx=a + 600*4*x + 30*4*y
mov eax, DWORD PTR _z$[ebp]
mov ecx, DWORD PTR _value$[ebp]
mov DWORD PTR [edx+eax*4], ecx ; *(edx+z*4)=
pop ebp
ret 0
_insert ENDP
_TEXT ENDS
, . insert() -
address = 6004x+304y+4z, .
, int 32- (4 ), 4.
x = dword ptr 8
y = dword ptr 0Ch
z = dword ptr 10h
value = dword ptr 14h
push ebp
mov ebp, esp
push ebx
mov ebx, [ebp+x]
mov eax, [ebp+y]
mov ecx, [ebp+z]
lea edx, [eax+eax] ; edx=y*2
mov eax, edx ; eax=y*2
shl eax, 4 ; eax=(y*2)<<4 = y*2*16 = y*32
sub eax, edx ; eax=y*32 y*2=y*30
imul edx, ebx, 600 ; edx=x*600
add eax, edx ; eax=eax+edx=y*30 + x*600
lea edx, [eax+ecx] ; edx=y*30 + x*600 + z
mov eax, [ebp+value]
mov dword ptr ds:a[edx*4], eax ; *(a+edx*4)=
pop ebx
pop ebp
retn
insert endp
296
18. 18.
18.27: Xcode 4.6.3 (LLVM) ( Thumb)
_insert
value = 0x10
z = 0xC
y = 8
x = 4
; 4 int
SUB SP, SP, #0x10
MOV R9, 0xFC2 ; a
ADD R9, PC
LDR.W R9, [R9]
STR R0, [SP,#0x10+x]
STR R1, [SP,#0x10+y]
STR R2, [SP,#0x10+z]
STR R3, [SP,#0x10+value]
LDR R0, [SP,#0x10+value]
LDR R1, [SP,#0x10+z]
LDR R2, [SP,#0x10+y]
LDR R3, [SP,#0x10+x]
MOV R12, 2400
MUL.W R3, R3, R12
ADD R3, R9
MOV R9, 120
MUL.W R2, R2, R9
ADD R2, R3
LSLS R1, R1, #2 ; R1=R1<<2
ADD R1, R2
STR R0, [R1] ; R1
; , 4
ADD SP, SP, #0x10
BX LR
LLVM , .
.
, .
RSB (Reverse Subtract). , SUB, -
. ? SUB RSB ,
, : (LSL#4). . -
, , .
, RSB.
LDR.W R9, [R9] LEA (A.6.2 (. 965)) x86, , .
, .
297
18. 18.
MIPS
, GCC a 64KiB-, -
Global Pointer.
.comm a:0x1770
18.6.4.
, .
: 83.2 (. 852).
18.7.
, : .18.8. ,
, .
? , :
#include <stdio.h>
#include <assert.h>
298
18. 18.
{ 'J','u','n','e', 0, 0, 0, 0, 0, 0 },
{ 'J','u','l','y', 0, 0, 0, 0, 0, 0 },
{ 'A','u','g','u','s','t', 0, 0, 0, 0 },
{ 'S','e','p','t','e','m','b','e','r', 0 },
{ 'O','c','t','o','b','e','r', 0, 0, 0 },
{ 'N','o','v','e','m','b','e','r', 0, 0 },
{ 'D','e','c','e','m','b','e','r', 0, 0 }
};
// 0..11
const char* get_month2 (int month)
{
return &month2[month][0];
};
get_month2 PROC
; 64-,
movsxd rax, ecx
lea rcx, QWORD PTR [rax+rax*4]
; RCX=+*4=*5
lea rax, OFFSET FLAT:month2
; RAX=
lea rax, QWORD PTR [rax+rcx*2]
; RAX= + RCX*2= + *5*2= + *10
ret 0
get_month2 ENDP
. ,
: pointer_to_the_table + month 10. LEA,
MUL MOV.
10 . , September (9 ) ,
10 . ,
(10 ). , , ,
.
GCC 4.9 :
LEA 10.
-.
299
18. 18.
movsx rdx, eax
; RDX = ,
mov rax, rdx
; RAX =
sal rax, 2
; RAX = <<2 = *4
add rax, rdx
; RAX = RAX+RDX = *4+ = *5
add rax, rax
; RAX = RAX*2 = *5*2 = *10
add rax, OFFSET FLAT:month2
; RAX = *10 +
pop rbp
ret
MSVC IMUL:
: ?
, . ,
. , ,
.
Keil ARM :
300
18. 18.
ADD r0,r0,r0,LSL #2
; R0 = R0+R0<<2 = R0+R0*4 = *5
ADD r0,r1,r0,LSL #1
; R0 = R1+R0<<2 = + *5*2 = + *10
BX lr
18.7.2. ARM64
18.7.3. MIPS
301
18. 18.
aDecember: .ascii "December"<0>
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0
18.7.4.
. Oracle RDBMS, .
, . , ,
.
18.8.
, .
, . .
18.9.
18.9.1. #1
(/O1: ).
302
18. 18.
ADD r8,r10,r0,LSL #5
ADD r7,r11,r0,LSL #5
ADD r6,r9,r0,LSL #5
|L0.44|
ADD r0,r8,r4,LSL #3
LDM r0,{r2,r3}
ADD r1,r7,r4,LSL #3
LDM r1,{r0,r1}
BL __aeabi_dadd
ADD r2,r6,r4,LSL #3
ADD r4,r4,#1
STM r2,{r0,r1}
CMP r4,#0x64
BLT |L0.44|
ADD r5,r5,#1
CMP r5,#0xc8
BLT |L0.20|
POP {r4r12,pc}
303
18. 18.
str wzr, [sp,40]
b .L3
.L4:
ldr w1, [sp,44]
mov w0, 100
mul w0, w1, w0
sxtw x1, w0
ldrsw x0, [sp,40]
add x0, x1, x0
lsl x0, x0, 3
ldr x1, [sp,8]
add x0, x1, x0
ldr w2, [sp,44]
mov w1, 100
mul w1, w2, w1
sxtw x2, w1
ldrsw x1, [sp,40]
add x1, x2, x1
lsl x1, x1, 3
ldr x2, [sp,24]
add x1, x2, x1
ldr x2, [x1]
ldr w3, [sp,44]
mov w1, 100
mul w1, w3, w1
sxtw x3, w1
ldrsw x1, [sp,40]
add x1, x3, x1
lsl x1, x1, 3
ldr x3, [sp,16]
add x1, x3, x1
ldr x1, [x1]
fmov d0, x2
fmov d1, x1
fadd d0, d0, d1
fmov x1, d0
str x1, [x0]
ldr w0, [sp,40]
add w0, w0, 1
str w0, [sp,40]
.L3:
ldr w0, [sp,40]
cmp w0, 99
ble .L4
ldr w0, [sp,44]
add w0, w0, 1
str w0, [sp,44]
.L2:
ldr w0, [sp,44]
cmp w0, 199
ble .L5
add sp, sp, 48
ret
304
18. 18.
lwc1 $f3, 0($v1)
lwc1 $f1, 0($t0)
addiu $v0, 1
add.d $f0, $f2, $f0
addiu $v1, 8
swc1 $f0, 4($a3)
swc1 $f1, 0($a3)
addiu $t0, 8
bne $v0, $t1, loc_20
addiu $a3, 8
addiu $t2, 0x320
bne $t2, $t3, loc_10
addiu $a0, 0x320
jr $ra
or $at, $zero
G.1.12 (. 988).
18.9.2. #2
305
18. 18.
?m@@YAXPAN00@Z ENDP ; m
(/O1: ).
18.44: Keil 6/2013 ( ARM)
PUSH {r0r2,r4r11,lr}
SUB sp,sp,#8
MOV r5,#0
|L0.12|
LDR r1,[sp,#0xc]
ADD r0,r5,r5,LSL #3
ADD r0,r0,r5,LSL #4
ADD r1,r1,r0,LSL #5
STR r1,[sp,#0]
LDR r1,[sp,#8]
MOV r4,#0
ADD r11,r1,r0,LSL #5
LDR r1,[sp,#0x10]
ADD r10,r1,r0,LSL #5
|L0.52|
MOV r0,#0
MOV r1,r0
ADD r7,r10,r4,LSL #3
STM r7,{r0,r1}
MOV r6,r0
LDR r0,[sp,#0]
ADD r8,r11,r4,LSL #3
ADD r9,r0,r4,LSL #3
|L0.84|
LDM r9,{r2,r3}
LDM r8,{r0,r1}
BL __aeabi_dmul
LDM r7,{r2,r3}
BL __aeabi_dadd
ADD r6,r6,#1
STM r7,{r0,r1}
CMP r6,#0xc8
BLT |L0.84|
ADD r4,r4,#1
CMP r4,#0x12c
BLT |L0.52|
ADD r5,r5,#1
CMP r5,#0x64
BLT |L0.12|
ADD sp,sp,#0x14
POP {r4r11,pc}
306
18. 18.
STR r0,[r2,#0]
MOVS r6,r0
STR r0,[r2,#4]
|L0.44|
LDR r0,[sp,#8]
ADDS r0,r0,r4
LDM r0!,{r2,r3}
LDR r0,[sp,#4]
ADDS r1,r0,r4
LDM r1,{r0,r1}
BL __aeabi_dmul
ADDS r3,r7,r4
LDM r3,{r2,r3}
BL __aeabi_dadd
ADDS r2,r7,r4
ADDS r6,r6,#1
STM r2!,{r0,r1}
CMP r6,#0xc8
BLT |L0.44|
MOVS r0,#0xff
ADDS r5,r5,#1
ADDS r0,r0,#0x2d
CMP r5,r0
BLT |L0.32|
LDR r0,[sp,#0]
ADDS r0,r0,#1
CMP r0,#0x64
STR r0,[sp,#0]
BLT |L0.8|
ADD sp,sp,#0x1c
POP {r4r7,pc}
307
18. 18.
mul w1, w2, w1
sxtw x2, w1
ldrsw x1, [sp,40]
add x1, x2, x1
lsl x1, x1, 3
ldr x2, [sp,8]
add x1, x2, x1
ldr x2, [x1]
ldr w3, [sp,44]
mov w1, 100
mul w1, w3, w1
sxtw x3, w1
ldrsw x1, [sp,40]
add x1, x3, x1
lsl x1, x1, 3
ldr x3, [sp,24]
add x1, x3, x1
ldr x3, [x1]
ldr w4, [sp,44]
mov w1, 100
mul w1, w4, w1
sxtw x4, w1
ldrsw x1, [sp,40]
add x1, x4, x1
lsl x1, x1, 3
ldr x4, [sp,16]
add x1, x4, x1
ldr x1, [x1]
fmov d0, x3
fmov d1, x1
fmul d0, d0, d1
fmov x1, d0
fmov d0, x2
fmov d1, x1
fadd d0, d0, d1
fmov x1, d0
str x1, [x0]
ldr w0, [sp,36]
add w0, w0, 1
str w0, [sp,36]
.L4:
ldr w0, [sp,36]
cmp w0, 199
ble .L5
ldr w0, [sp,40]
add w0, w0, 1
str w0, [sp,40]
.L3:
ldr w0, [sp,40]
cmp w0, 299
ble .L6
ldr w0, [sp,44]
add w0, w0, 1
str w0, [sp,44]
.L2:
ldr w0, [sp,44]
cmp w0, 99
ble .L7
add sp, sp, 48
ret
308
18. 18.
addu $t0, $a0, $t4
addu $a3, $a1, $t4
move $v1, $a2
move $t2, $zero
G.1.12 (. 988).
18.9.3. #3
?
, .
309
18. 18.
18.50: Keil 6/2013 ( Thumb)
f PROC
MOVS r3,#0xf
LSLS r3,r3,#6
MULS r1,r3,r1
ADDS r0,r1,r0
LSLS r1,r2,#3
ADDS r1,r0,r1
LDM r1,{r0,r1}
BX lr
ENDP
G.1.12 (. 988)
18.9.4. #4
?
, .
310
18. 18.
RSB r1,r1,r1,LSL #4
ADD r1,r1,r1,LSL #2
ADD r0,r0,r1,LSL #8
ADD r1,r2,r2,LSL #2
ADD r0,r0,r1,LSL #6
LDR r0,[r0,r3,LSL #2]
BX lr
ENDP
G.1.12 (. 988)
18.9.5. #5
tv759 = 4 ; size = 4
311
18. 18.
_main PROC
push ecx
push ebx
push ebp
push esi
xor edx, edx
push edi
xor esi, esi
xor edi, edi
xor ebx, ebx
xor ebp, ebp
mov DWORD PTR tv759[esp+20], edx
mov eax, OFFSET _tbl+4
npad 8 ; align next label
$LL6@main:
lea ecx, DWORD PTR [edx+edx]
mov DWORD PTR [eax+4], ecx
mov ecx, DWORD PTR tv759[esp+20]
add DWORD PTR tv759[esp+20], 3
mov DWORD PTR [eax+8], ecx
lea ecx, DWORD PTR [edx*4]
mov DWORD PTR [eax+12], ecx
lea ecx, DWORD PTR [edx*8]
mov DWORD PTR [eax], edx
mov DWORD PTR [eax+16], ebp
mov DWORD PTR [eax+20], ebx
mov DWORD PTR [eax+24], edi
mov DWORD PTR [eax+32], esi
mov DWORD PTR [eax4], 0
mov DWORD PTR [eax+28], ecx
add eax, 40
inc edx
add ebp, 5
add ebx, 6
add edi, 7
add esi, 9
cmp eax, OFFSET _tbl+404
jl SHORT $LL6@main
pop edi
pop esi
pop ebp
xor eax, eax
pop ebx
pop ecx
ret 0
_main ENDP
|L0.60|
312
18. 18.
DCD ||.bss||
tbl
% 400
DCW 0x0000
|L0.40|
DCD ||.bss||
tbl
% 400
313
18. 18.
ldr w0, [sp,8]
cmp w0, 9
ble .L4
ldr w0, [sp,12]
add w0, w0, 1
str w0, [sp,12]
.L2:
ldr w0, [sp,12]
cmp w0, 9
ble .L5
mov w0, 0
add sp, sp, 16
ret
var_18 = 0x18
var_10 = 0x10
var_C = 0xC
var_4 = 4
314
18. 18.
lw $v0, 0x18+var_C($fp)
or $at, $zero
slti $v0, 0xA
bnez $v0, loc_24
or $at, $zero
move $v0, $zero
move $sp, $fp
lw $fp, 0x18+var_4($sp)
addiu $sp, 0x18
jr $ra
or $at, $zero
G.1.12 (. 989)
315
19. 19.
19
1 . ,
bool, .
19.1. -
19.1.1. x86
Win32 API:
HANDLE fh;
(MSVC 2010):
WinNT.h:
19.2: WinNT.h
#define GENERIC_READ (0x80000000L)
#define GENERIC_WRITE (0x40000000L)
#define GENERIC_EXECUTE (0x20000000L)
#define GENERIC_ALL (0x10000000L)
1 bit elds
2 msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx
316
19. 19.
TEST. , ,
(ebp+dwDesiredAccess+3) 0x40 ( GENERIC_WRITE). TEST
AND, ( CMP SUB,
(7.3.1 (. 80))).
:
if ((dwDesiredAccess&0x40000000) == 0) goto loc_7C83D417
AND , ZF JZ .
, dwDesiredAccess 0x40000000 AND 0,
ZF .
GCC 4.4.1 Linux:
#include <stdio.h>
#include <fcntl.h>
void main()
{
int handle;
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 20h
mov [esp+20h+var_1C], 42h
mov [esp+20h+var_20], offset aFile ; "file"
call _open
mov [esp+20h+var_4], eax
leave
retn
main endp
open() libc.so.6, :
, open() - Linux.
, Linux Linux , -
.
sys_open do_sys_open Linux 2.6.
do_filp_open() ( fs/namei.c).
N.B. ,
. fastcall (64.3 (. 690)). ,
, . GCC regparm3 ,
, .
3 ohse.de/uwe/articles/gcc-attributes.html#func-regparm
317
19. 19.
Linux 2.6 -mregparm=34 5 .
, EAX, EDX ECX,
. , , .
, 2.6.31, Ubuntu, IDA, do_filp_open().
- ( ):
GCC . , ,
, ( register allocator),
.
:
19.1.2. ARM
318
19. 19.
error = do_last(nd, &path, file, op, &opened, pathname);
...
}
IDA, ARM:
19.2.
:
#include <stdio.h>
319
19. 19.
#define IS_SET(flag, bit) ((flag) & (bit))
#define SET_BIT(var, bit) ((var) |= (bit))
#define REMOVE_BIT(var, bit) ((var) &= ~(bit))
int f(int a)
{
int rt=a;
return rt;
};
int main()
{
f(0x12340678);
};
19.2.1. x86
MSVC
(MSVC 2010):
OR , .
AND . , AND , . ,
AND , , ,
( 0 ). .
320
19. 19.
OllyDbg
OllyDbg. , :
0x200 (00000000000000000001000000000) (.. 10- ( )).
0x200 0xFFFFFDFF (11111111111111111110111111111).
0x4000 (00000000000000100000000000000) (.. 15- ).
: 0x12340678 (10010001101000000011001111000). , :
321
19. 19.
OR :
. 19.2: OllyDbg: OR
322
19. 19.
( ):
323
19. 19.
AND :
10- (, , 10-)
0x12344478 (10010001101000100010001111000).
MSVC
MSVC (/Ox), :
19.11: MSVC
_a$ = 8 ; size = 4
_f PROC
mov eax, DWORD PTR _a$[esp4]
and eax, 513 ; fffffdffH
or eax, 16384 ; 00004000H
ret 0
_f ENDP
GCC
GCC 4.4.1 :
19.12: GCC
public f
f proc near
push ebp
mov ebp, esp
sub esp, 10h
mov eax, [ebp+arg_0]
mov [ebp+var_4], eax
or [ebp+var_4], 4000h
and [ebp+var_4], 0FFFFFDFFh
mov eax, [ebp+var_4]
leave
retn
f endp
, , MSVC .
GCC -O3:
324
19. 19.
GCC
19.13: GCC
public f
f proc near
push ebp
mov ebp, esp
mov eax, [ebp+arg_0]
pop ebp
or ah, 40h
and ah, 0FDh
retn
f endp
. , AH EAX. 8-
15- .
7 ( ) 6 5 4 3 2 1 0
RAXx64
EAX
AX
AH AL
N.B. 16- 8086 AX 8- AL (-
) AH (). 80386 32-, EAX,
, AX/ AH/ AL.
- , x86 16- 8086, 16-
32-. or ah, 40h 3 . or
eax, 04000h, 5 , 6 ( EAX).
GCC regparm
-O3, regparm=3,
, :
19.14: GCC
public f
f proc near
push ebp
or ah, 40h
mov ebp, esp
and ah, 0FDh
pop ebp
retn
f endp
EAX, . ,
(push ebp / mov ebp,esp) (pop ebp) ,
GCC . ,
inline- (43 (. 522)).
325
19. 19.
ORR , OR x86.
.
, LLVM, , , :
REMOVE_BIT (rt, 0x4200);
SET_BIT (rt, 0x4000);
. 0x4200? , LLVM6 . ,
, .
, (91 (. 899)).
Xcode 4.6.3 (LLVM) Thumb .
:
int f(int a)
{
int rt=a;
return rt;
};
326
19. 19.
19.2.6. ARM64: GCC (Linaro) 4.9
GCC , :
19.2.8. MIPS
ORI , , , I .
, AND. ANDI, 0xFFFFFDFF
, 0xFFFFFDFF $V0,
AND, .
19.3.
/++ .
x86 SHL (SHift Left) SHR (SHift Right) .
- : 2n (.. 1, 2, 4, 8,
..): 16.1.2 (. 210), 16.2.1 (. 215).
,
.
327
19. 19.
19.4. : FPU
, oat IEEE 754:
31 30 23 22 0
( S )
MSB7 . , FPU-?
#include <stdio.h>
int main()
{
printf ("my_abs():\n");
printf ("%f\n", my_abs (123.456));
printf ("%f\n", my_abs (456.123));
printf ("set_sign():\n");
printf ("%f\n", set_sign (123.456));
printf ("%f\n", set_sign (456.123));
printf ("negate():\n");
printf ("%f\n", negate (123.456));
printf ("%f\n", negate (456.123));
};
/++ oat
. : my_abs() MSB; set_sign() MSB negate()
.
19.4.1. - XOR
XOR ( ) - () . -
, XOR 1 :
0 0 0
0 1 1
1 0 1
1 1 0
, XOR 0 , .. . XOR
.
19.4.2. x86
:
7 Most signicant bit/byte ( /)
328
19. 19.
19.21: MSVC 2012
_tmp$ = 8
_i$ = 8
_my_abs PROC
and DWORD PTR _i$[esp4], 2147483647 ; 7fffffffH
fld DWORD PTR _tmp$[esp4]
ret 0
_my_abs ENDP
_tmp$ = 8
_i$ = 8
_set_sign PROC
or DWORD PTR _i$[esp4], 2147483648 ; 80000000H
fld DWORD PTR _tmp$[esp4]
ret 0
_set_sign ENDP
_tmp$ = 8
_i$ = 8
_negate PROC
xor DWORD PTR _i$[esp4], 2147483648 ; 80000000H
fld DWORD PTR _tmp$[esp4]
ret 0
_negate ENDP
oat , .
AND OR . XOR .
ST0, .
MSVC 2012 x64:
tmp$ = 8
i$ = 8
set_sign PROC
movss DWORD PTR [rsp+8], xmm0
mov eax, DWORD PTR i$[rsp]
bts eax, 31
mov DWORD PTR tmp$[rsp], eax
movss xmm0, DWORD PTR tmp$[rsp]
ret 0
set_sign ENDP
tmp$ = 8
i$ = 8
negate PROC
movss DWORD PTR [rsp+8], xmm0
mov eax, DWORD PTR i$[rsp]
btc eax, 31
mov DWORD PTR tmp$[rsp], eax
movss xmm0, DWORD PTR tmp$[rsp]
ret 0
negate ENDP
-, XMM0,
: BTR, BTS, BTC.
329
19. 19.
(BTR: reset), (BTS: set)
(BTC: complement). 31- MSB, .
, XMM0,
XMM0 Win64.
19.4.3. MIPS
set_sign:
; 1:
mfc1 $v0, $f12
lui $v1, 0x8000
; $v1=0x80000000
; :
or $v0, $v1, $v0
; 1:
mtc1 $v0, $f0
;
jr $ra
or $at, $zero ; branch delay slot
negate:
; 1:
mfc1 $v0, $f12
lui $v1, 0x8000
; $v1=0x80000000
; :
xor $v0, $v1, $v0
; 1:
mtc1 $v0, $f0
;
jr $ra
or $at, $zero ; branch delay slot
19.4.4. ARM
set_sign PROC
; :
330
19. 19.
ORR r0,r0,#0x80000000
BX lr
ENDP
negate PROC
; :
EOR r0,r0,#0x80000000
BX lr
ENDP
set_sign PROC
MOVS r1,#1
; r1=1
LSLS r1,r1,#31
; r1=1<<31=0x80000000
ORRS r0,r0,r1
; r0=r0 | 0x80000000
BX lr
ENDP
negate PROC
MOVS r1,#1
; r1=1
LSLS r1,r1,#31
; r1=1<<31=0x80000000
EORS r0,r0,r1
; r0=r0 ^ 0x80000000
BX lr
ENDP
Thumb 16- , , -
MOVS/ LSLS 0x80000000. : 1 << 31 = 0x80000000.
my_abs : (i << 1) >> 1. .
, input << 1, MSB ( ) .
result >> 1, , MSB ,
. , LSLS/ LSRS MSB.
set_sign
331
19. 19.
; S0 R2:
FMRS R2, S0
; :
ORR R3, R2, #0x80000000
; R3 S0:
FMSR S0, R3
BX LR
negate
; S0 R2:
FMRS R2, S0
; :
ADD R3, R2, #0x80000000
; R3 S0:
FMSR S0, R3
BX LR
19.5.
, - .
population count8 .
#include <stdio.h>
return rt;
};
int main()
{
f(0x12345678); // test
};
i 0 31, 1 i 1 0x80000000. , -
n . .. , 1 i
32- . .
1 i i = 0 . . . 31:
8 x86- ( SSE4) POPCNT
332
19. 19.
/++
10 1 1 1
11 21 2 2
12 22 4 4
13 23 8 8
14 24 16 0x10
15 25 32 0x20
16 26 64 0x40
17 27 128 0x80
18 28 256 0x100
19 29 512 0x200
1 10 210 1024 0x400
1 11 211 2048 0x800
1 12 212 4096 0x1000
1 13 213 8192 0x2000
1 14 214 16384 0x4000
1 15 215 32768 0x8000
1 16 216 65536 0x10000
1 17 217 131072 0x20000
1 18 218 262144 0x40000
1 19 219 524288 0x80000
1 20 220 1048576 0x100000
1 21 221 2097152 0x200000
1 22 222 4194304 0x400000
1 23 223 8388608 0x800000
1 24 224 16777216 0x1000000
1 25 225 33554432 0x2000000
1 26 226 67108864 0x4000000
1 27 227 134217728 0x8000000
1 28 228 268435456 0x10000000
1 29 229 536870912 0x20000000
1 30 230 1073741824 0x40000000
1 31 231 2147483648 0x80000000
- ( ), reverse engineer-,
. , , , -
.
. , ssl_private.h
Apache 2.4.6:
/**
* Define the SSL options
*/
#define SSL_OPT_NONE (0)
#define SSL_OPT_RELSET (1<<0)
#define SSL_OPT_STDENVVARS (1<<1)
#define SSL_OPT_EXPORTCERTDATA (1<<3)
#define SSL_OPT_FAKEBASICAUTH (1<<4)
#define SSL_OPT_STRICTREQUIRE (1<<5)
#define SSL_OPT_OPTRENEGOTIATE (1<<6)
#define SSL_OPT_LEGACYDNFORMAT (1<<7)
.
IS_SET a. IS_SET (AND)
0 , , . /++, if() ,
, 123456, .
19.5.1. x86
MSVC
(MSVC 2010):
333
19. 19.
19.27: MSVC 2010
_rt$ = 8 ; size = 4
_i$ = 4 ; size = 4
_a$ = 8 ; size = 4
_f PROC
push ebp
mov ebp, esp
sub esp, 8
mov DWORD PTR _rt$[ebp], 0
mov DWORD PTR _i$[ebp], 0
jmp SHORT $LN4@f
$LN3@f:
mov eax, DWORD PTR _i$[ebp] ; i
add eax, 1
mov DWORD PTR _i$[ebp], eax
$LN4@f:
cmp DWORD PTR _i$[ebp], 32 ; 00000020H
jge SHORT $LN2@f ; ?
mov edx, 1
mov ecx, DWORD PTR _i$[ebp]
shl edx, cl ; EDX=EDX<<CL
and edx, DWORD PTR _a$[ebp]
je SHORT $LN1@f ; AND 0?
;
mov eax, DWORD PTR _rt$[ebp] ; ,
add eax, 1 ; rt
mov DWORD PTR _rt$[ebp], eax
$LN1@f:
jmp SHORT $LN3@f
$LN2@f:
mov eax, DWORD PTR _rt$[ebp]
mov esp, ebp
pop ebp
ret 0
_f ENDP
334
19. 19.
OllyDbg
OllyDbg. 0x12345678.
i = 1, , i ECX:
EDX 1. SHL.
335
19. 19.
SHL :
EDX 1 1 ( 2). .
336
19. 19.
AND ZF 1, , (0x12345678) 9 2 0:
. , ,
: JZ .
337
19. 19.
i 4. SHL :
338
19. 19.
EDX =1 4 ( 0x10 16):
339
19. 19.
AND :
13. 0x12345678.
GCC
GCC 4.4.1:
push ebp
mov ebp, esp
push ebx
sub esp, 10h
mov [ebp+rt], 0
mov [ebp+i], 0
jmp short loc_80483EF
loc_80483D0:
mov eax, [ebp+i]
mov edx, 1
mov ebx, edx
mov ecx, eax
shl ebx, cl
mov eax, ebx
and eax, [ebp+arg_0]
test eax, eax
jz short loc_80483EB
add [ebp+rt], 1
loc_80483EB:
add [ebp+i], 1
loc_80483EF:
cmp [ebp+i], 1Fh
jle short loc_80483D0
mov eax, [ebp+rt]
add esp, 10h
pop ebx
340
19. 19.
pop ebp
retn
f endp
19.5.2. x64
, 64- :
#include <stdio.h>
#include <stdint.h>
int f(uint64_t a)
{
uint64_t i;
int rt=0;
return rt;
};
GCC 4.8.2
341
19. 19.
GCC 4.8.2
, . , ,
rt , rt 1
( 6), EDX. , 1, CMOVNE10 (
CMOVNZ11 ) rt EDX ( rt)
EAX ( rt ). ,
, .. 64 , .
, ( ) (-
rt ). CPU
: 33.1 (. 476).
REP RET ( F3 C3) FATRET MSVC.
RET, AMD , RET : [AMD13b,
p.15] 12 .
MSVC 2010
342
19. 19.
:
RDX R8
0x0000000000000001 64
0x0000000000000002 63
0x0000000000000004 62
0x0000000000000008 61
... ...
0x4000000000000000 2
0x8000000000000000 1
FATRET, : 19.5.2 (. 342).
MSVC 2012
343
19. 19.
TST TEST x86.
(41.2.1 (. 510)), ARM . ,
LSL (Logical Shift Left), LSR (Logical Shift Right), ASR (Arithmetic Shift Right), ROR (Rotate Right) RRX (Rotate Right with Extend)
, MOV, TST, CMP, ADD, SUB, RSB13 .
, , .
, TST R1, R2,LSL R3 R1 (R2 R3).
344
19. 19.
19.35: GCC (Linaro) 4.8
f:
sub sp, sp, #32
str x0, [sp,8] ; "a" Register Save Area
str wzr, [sp,24] ; rt=0
str wzr, [sp,28] ; i=0
b .L2
.L4:
ldr w0, [sp,28]
mov x1, 1
lsl x0, x1, x0 ; X0 = X1<<X0 = 1<<i
mov x1, x0
; X1 = 1<<1
ldr x0, [sp,8]
; X0 = a
and x0, x1, x0
; X0 = X1&X0 = (1<<i) & a
; X0 ? .L3, "rt"
cmp x0, xzr
beq .L3
; rt++
ldr w0, [sp,24]
add w0, w0, 1
str w0, [sp,24]
.L3:
; i++
ldr w0, [sp,28]
add w0, w0, 1
str w0, [sp,28]
.L2:
; i<=63? .L4
ldr w0, [sp,28]
cmp w0, 63
ble .L4
; rt
ldr w0, [sp,24]
add sp, sp, 32
ret
19.5.7. MIPS
GCC
loc_20:
li $v1, 1
lw $v0, 0x18+i($fp)
or $at, $zero ; load delay slot, NOP
sllv $v0, $v1, $v0
345
19. 19.
; $v0 = 1<<i
move $v1, $v0
lw $v0, 0x18+a($fp)
or $at, $zero ; load delay slot, NOP
and $v0, $v1, $v0
; $v0 = a&(1<<i)
; a&(1<<i) ? loc_58:
beqz $v0, loc_58
or $at, $zero
; , a&(1<<i)!=0, "rt":
lw $v0, 0x18+rt($fp)
or $at, $zero ; load delay slot, NOP
addiu $v0, 1
sw $v0, 0x18+rt($fp)
loc_58:
; i:
lw $v0, 0x18+i($fp)
or $at, $zero ; load delay slot, NOP
addiu $v0, 1
sw $v0, 0x18+i($fp)
loc_68:
; i 0x20 (32).
; loc_20, 0x20 (32):
lw $v0, 0x18+i($fp)
or $at, $zero ; load delay slot, NOP
slti $v0, 0x20 # ' '
bnez $v0, loc_20
or $at, $zero ; branch delay slot, NOP
; . rt:
lw $v0, 0x18+rt($fp)
move $sp, $fp ; load delay slot
lw $fp, 0x18+var_4($sp)
addiu $sp, 0x18 ; load delay slot
jr $ra
or $at, $zero ; branch delay slot, NOP
: ,
. SLLV Shift Word Left Logical Variable, SLL
SLL (, , ), SLL .
GCC
. . ? SLLV
, SLLV.
, : 33.1 (. 476).
loc_14:
and $a1, $a0
; $a1 = a&(1<<i)
; i:
addiu $v1, 1
; loc\_28 a&(1<<i)==0 rt:
beqz $a1, loc_28
addiu $a2, $v0, 1
346
19. 19.
; BEQZ , rt $v0:
move $v0, $a2
loc_28:
; i!=32, loc_14 :
bne $v1, $a3, loc_14
sllv $a1, $t0, $v1
;
jr $ra
or $at, $zero ; branch delay slot, NOP
19.6.
, /++ , x86 SHR/ SHL ( ), SAR/ SHL
( ).
ARM LSR/ LSL ( ), ASR/ LSL ( ).
( data processing instructions).
19.6.1. ( )
, 1000000 (0x40) :
19.38: /++
if (input&0x40)
...
19.39: x86
TEST REG, 40h
JNZ is_set
;
19.40: x86
TEST REG, 40h
JZ is_cleared
;
AND TEST, .
19.6.2. ( )
/++ ( n ,
):
19.42: /++
if ((value>>n)&1)
....
x86- :
19.43: x86
; REG=input_value
; CL=n
SHR REG, CL
AND REG, 1
347
19. 19.
( 1 n , , ):
19.44: /++
if (value & (1<<n))
....
x86-:
19.45: x86
; CL=n
MOV REG, 1
SHL REG, CL
AND input_value, REG
19.6.3. ( )
19.46: /++
value=value|0x40;
19.47: x86
OR REG, 40h
19.6.4. ( )
19.49: /++
value=value|(1<<n);
x86-:
19.50: x86
; CL=n
MOV REG, 1
SHL REG, CL
OR input_value, REG
19.6.5. ( )
(AND) :
19.51: /++
value=value&(~0x40);
19.52: x86
AND REG, 0FFFFFFBFh
19.53: x64
AND REG, 0FFFFFFFFFFFFFFBFh
.
ARM ARM BIC, NOT +AND:
19.54: ARM ( ARM)
BIC R0, R0, #0x40
348
19. 19.
19.6.6. ( )
19.55: /++
value=value&(~(1<<n));
19.56: x86
; CL=n
MOV REG, 1
SHL REG, CL
NOT REG
AND input_value, REG
19.7.
19.7.1. #1
349
19. 19.
ORRS r0,r0,r1
BX lr
ENDP
: G.1.13 (. 989).
19.7.2. #2
350
19. 19.
ADD r1,r1,#4
ADD r2,r2,r2,LSL #2
CMP r1,#0x1c
LSL r2,r2,#1
BLE |L0.16|
BX lr
ENDP
351
19. 19.
f:
srl $v0, $a0, 8
srl $a3, $a0, 20
andi $a3, 0xF
andi $v0, 0xF
srl $a1, $a0, 12
srl $a2, $a0, 16
andi $a1, 0xF
andi $a2, 0xF
sll $t2, $v0, 4
sll $v1, $a3, 2
sll $t0, $v0, 2
srl $t1, $a0, 4
sll $t5, $a3, 7
addu $t0, $t2
subu $t5, $v1
andi $t1, 0xF
srl $v1, $a0, 28
sll $t4, $a1, 7
sll $t2, $a2, 2
sll $t3, $a1, 2
sll $t7, $a2, 7
srl $v0, $a0, 24
addu $a3, $t5, $a3
subu $t3, $t4, $t3
subu $t7, $t2
andi $v0, 0xF
sll $t5, $t1, 3
sll $t6, $v1, 8
sll $t2, $t0, 2
sll $t4, $t1, 1
sll $t1, $v1, 3
addu $a2, $t7, $a2
subu $t1, $t6, $t1
addu $t2, $t0, $t2
addu $t4, $t5
addu $a1, $t3, $a1
sll $t5, $a3, 2
sll $t3, $v0, 8
sll $t0, $v0, 3
addu $a3, $t5
subu $t0, $t3, $t0
addu $t4, $t2, $t4
sll $t3, $a2, 2
sll $t2, $t1, 6
sll $a1, 3
addu $a1, $t4, $a1
subu $t1, $t2, $t1
addu $a2, $t3
sll $t2, $t0, 6
sll $t3, $a3, 2
andi $a0, 0xF
addu $v1, $t1, $v1
addu $a0, $a1
addu $a3, $t3
subu $t0, $t2, $t0
sll $a2, 4
addu $a2, $a0, $a2
addu $v0, $t0, $v0
sll $a1, $v1, 2
sll $a3, 5
addu $a3, $a2, $a3
addu $v1, $a1
sll $v0, 6
addu $v0, $a3, $v0
sll $v1, 7
jr $ra
addu $v0, $v1, $v0
: G.1.13 (. 989).
352
19. 19.
19.7.3. #3
: G.1.13 (. 989).
19.7.4. #4
353
19. 19.
BNE |L0.24|
POP {r4,pc}
ENDP
354
19. 19.
: G.1.13 (. 990).
355
20. 20.
20
, , .
1 , ( , ),
.
#include <stdint.h>
// Numerical Recipes
#define RNG_a 1664525
#define RNG_c 1013904223
int my_rand ()
{
rand_state=rand_state*RNG_a;
rand_state=rand_state+RNG_c;
return rand_state & 0x7fff;
}
: ,
.
. [Pre+07].
/++ #define. . /++ ,
/++ . , ,
. ( ) -,
.
, my_rand()
0..32767. 32- , .
20.1. x86
_init$ = 8
_srand PROC
1
356
20. 20.
mov eax, DWORD PTR _init$[esp4]
mov DWORD PTR _rand_state, eax
ret 0
_srand ENDP
_TEXT SEGMENT
_rand PROC
imul eax, DWORD PTR _rand_state, 1664525
add eax, 1013904223 ; 3c6ef35fH
mov DWORD PTR _rand_state, eax
and eax, 32767 ; 00007fffH
ret 0
_rand ENDP
_TEXT ENDS
: . . my_srand()
rand_state.
my_rand() , rand_state, EAX.
:
_init$ = 8
_srand PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _init$[ebp]
mov DWORD PTR _rand_state, eax
pop ebp
ret 0
_srand ENDP
_TEXT SEGMENT
_rand PROC
push ebp
mov ebp, esp
imul eax, DWORD PTR _rand_state, 1664525
mov DWORD PTR _rand_state, eax
mov ecx, DWORD PTR _rand_state
add ecx, 1013904223 ; 3c6ef35fH
mov DWORD PTR _rand_state, ecx
mov eax, DWORD PTR _rand_state
and eax, 32767 ; 00007fffH
pop ebp
ret 0
_rand ENDP
_TEXT ENDS
20.2. x64
x64 , 32- 64- (
int). my_srand() ECX, :
init$ = 8
my_srand PROC
357
20. 20.
; ECX =
mov DWORD PTR rand_state, ecx
ret 0
my_srand ENDP
_TEXT SEGMENT
my_rand PROC
imul eax, DWORD PTR rand_state, 1664525 ; 0019660dH
add eax, 1013904223 ; 3c6ef35fH
mov DWORD PTR rand_state, eax
and eax, 32767 ; 00007fffH
ret 0
my_rand ENDP
_TEXT ENDS
GCC .
my_rand PROC
LDR r0,|L0.52| ; rand_state
LDR r2,|L0.56| ; RNG_a
LDR r1,[r0,#0] ; rand_state
MUL r1,r2,r1
LDR r2,|L0.60| ; RNG_c
ADD r1,r1,r2
STR r1,[r0,#0] ; rand_state
; AND 0x7FFF:
LSL r0,r1,#17
LSR r0,r0,#17
BX lr
ENDP
|L0.52|
DCD ||.data||
|L0.56|
DCD 0x0019660d
|L0.60|
DCD 0x3c6ef35f
rand_state
DCD 0x00000000
Keil Thumb .
20.4. MIPS
358
20. 20.
20.5: GCC 4.4.5 (IDA)
my_srand:
; $a0 rand_state:
lui $v0, (rand_state >> 16)
jr $ra
sw $a0, rand_state
my_rand:
; rand_state $v0:
lui $v1, (rand_state >> 16)
lw $v0, rand_state
or $at, $zero ; load delay slot
; rand_state $v0 1664525 (RNG_a):
sll $a1, $v0, 2
sll $a0, $v0, 4
addu $a0, $a1, $a0
sll $a1, $a0, 6
subu $a0, $a1, $a0
addu $a0, $v0
sll $a1, $a0, 5
addu $a0, $a1
sll $a0, 3
addu $v0, $a0, $v0
sll $a0, $v0, 2
addu $v0, $a0
; 1013904223 (RNG_c)
; LI IDA LUI ORI
li $a0, 0x3C6EF35F
addu $v0, $a0
; rand_state:
sw $v0, (rand_state & 0xFFFF)($v1)
jr $ra
andi $v0, 0x7FFF ; branch delay slot
int f (int a)
{
return a*RNG_a;
}
, .
IDA, .
objdump : :
359
20. 20.
20.7: GCC 4.4.5 (objdump)
# objdump D rand_O3.o
...
00000000 <my_srand>:
0: 3c020000 lui v0,0x0
4: 03e00008 jr ra
8: ac440000 sw a0,0(v0)
0000000c <my_rand>:
c: 3c030000 lui v1,0x0
10: 8c620000 lw v0,0(v1)
14: 00200825 move at,at
18: 00022880 sll a1,v0,0x2
1c: 00022100 sll a0,v0,0x4
20: 00a42021 addu a0,a1,a0
24: 00042980 sll a1,a0,0x6
28: 00a42023 subu a0,a1,a0
2c: 00822021 addu a0,a0,v0
30: 00042940 sll a1,a0,0x5
34: 00852021 addu a0,a0,a1
38: 000420c0 sll a0,a0,0x3
3c: 00821021 addu v0,a0,v0
40: 00022080 sll a0,v0,0x2
44: 00441021 addu v0,v0,a0
48: 3c043c6e lui a0,0x3c6e
4c: 3484f35f ori a0,a0,0xf35f
50: 00441021 addu v0,v0,a0
54: ac620000 sw v0,0(v1)
58: 03e00008 jr ra
5c: 30427fff andi v0,v0,0x7fff
...
# objdump r rand_O3.o
...
...
my_srand(). , 0, R_MIPS_HI16, ,
8, R_MIPS_LO16. , .bss 0
( ) 8 ( ). rand_state
.bss. LUI SW
, . LUI
SW. SW
$V0 ( ).
my_rand(): R_MIPS_HI16
.bss LUI. rand_state $V1. -
LW 0x10 rand_state
$V1. SW 0x54
rand_state.
IDA , . .
360
20. 20.
20.5.
: 65.1 (. 697).
361
21. 21.
21
, /++ , , , -
, , 1 .
21.1: WinBase.h
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
:
#include <windows.h>
#include <stdio.h>
void main()
{
SYSTEMTIME t;
GetSystemTime (&t);
return;
};
(MSVC 2010):
362
21. 21.
push eax
call DWORD PTR __imp__GetSystemTime@4
movzx ecx, WORD PTR _t$[ebp+12] ; wSecond
push ecx
movzx edx, WORD PTR _t$[ebp+10] ; wMinute
push edx
movzx eax, WORD PTR _t$[ebp+8] ; wHour
push eax
movzx ecx, WORD PTR _t$[ebp+6] ; wDay
push ecx
movzx edx, WORD PTR _t$[ebp+2] ; wMonth
push edx
movzx eax, WORD PTR _t$[ebp] ; wYear
push eax
push OFFSET $SG78811 ; '%04d%02d%02d %02d:%02d:%02d', 0aH, 00H
call _printf
add esp, 28
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
16 sizeof(WORD)*8 ( 8
WORD).
, wYear. ,
GetSystemTime()3 SYSTEMTIME, ,
wYear, ! GetSystemTime() WORD
, 2 , , .., ..
363
21. 21.
21.1.1. OllyDbg
, , 9 2014, 22:29:52:
, 16 :
DE 07 0C 00 02 00 09 00 16 00 1D 00 34 00 D4 03
21.1.2.
, ,
. SYSTEMTIME, :
364
21. 21.
#include <windows.h>
#include <stdio.h>
void main()
{
WORD array[8];
GetSystemTime (array);
return;
};
:
systemtime2.c(7) : warning C4133: 'function' : incompatible types from 'WORD [8]' to 'LPSYSTEMTIME'
, :
_array$ = 16 ; size = 16
_main PROC
push ebp
mov ebp, esp
sub esp, 16
lea eax, DWORD PTR _array$[ebp]
push eax
call DWORD PTR __imp__GetSystemTime@4
movzx ecx, WORD PTR _array$[ebp+12] ; wSecond
push ecx
movzx edx, WORD PTR _array$[ebp+10] ; wMinute
push edx
movzx eax, WORD PTR _array$[ebp+8] ; wHoure
push eax
movzx ecx, WORD PTR _array$[ebp+6] ; wDay
push ecx
movzx edx, WORD PTR _array$[ebp+2] ; wMonth
push edx
movzx eax, WORD PTR _array$[ebp] ; wYear
push eax
push OFFSET $SG78573
call _printf
add esp, 28
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
!
. , ,
, , .
, . . , ,
, , ..
OllyDbg , , .
21.2. malloc()
, , , :
365
21. 21.
#include <windows.h>
#include <stdio.h>
void main()
{
SYSTEMTIME *t;
GetSystemTime (t);
free (t);
return;
};
(/Ox) , .
21.4: MSVC
_main PROC
push esi
push 16
call _malloc
add esp, 4
mov esi, eax
push esi
call DWORD PTR __imp__GetSystemTime@4
movzx eax, WORD PTR [esi+12] ; wSecond
movzx ecx, WORD PTR [esi+10] ; wMinute
movzx edx, WORD PTR [esi+8] ; wHour
push eax
movzx eax, WORD PTR [esi+6] ; wDay
push ecx
movzx ecx, WORD PTR [esi+2] ; wMonth
push edx
movzx edx, WORD PTR [esi] ; wYear
push eax
push ecx
push edx
push OFFSET $SG78833
call _printf
push esi
call _free
add esp, 32
xor eax, eax
pop esi
ret 0
_main ENDP
void main()
366
21. 21.
{
WORD *t;
GetSystemTime (t);
free (t);
return;
};
21.5: MSVC
$SG78594 DB '%04d%02d%02d %02d:%02d:%02d', 0aH, 00H
_main PROC
push esi
push 16
call _malloc
add esp, 4
mov esi, eax
push esi
call DWORD PTR __imp__GetSystemTime@4
movzx eax, WORD PTR [esi+12]
movzx ecx, WORD PTR [esi+10]
movzx edx, WORD PTR [esi+8]
push eax
movzx eax, WORD PTR [esi+6]
push ecx
movzx ecx, WORD PTR [esi+2]
push edx
movzx edx, WORD PTR [esi]
push eax
push ecx
push edx
push OFFSET $SG78594
call _printf
push esi
call _free
add esp, 32
xor eax, eax
pop esi
ret 0
_main ENDP
, . ,
, , .
21.3.1. Linux
, , tm time.h:
#include <stdio.h>
#include <time.h>
void main()
{
struct tm t;
time_t unix_time;
367
21. 21.
unix_time=time(NULL);
GCC 4.4.1:
, - , IDA .
:-) .
lea edx, [eax+76Ch] 0x76C (1900) EAX,
. . LEA (A.6.2 (. 965)).
368
21. 21.
GDB
GDB 4 :
21.7: GDB
dennis@ubuntuvm:~/polygon$ date
Mon Jun 2 18:10:37 EEST 2014
dennis@ubuntuvm:~/polygon$ gcc GCC_tm.c o GCC_tm
dennis@ubuntuvm:~/polygon$ gdb GCC_tm
GNU gdb (GDB) 7.6.1ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686linuxgnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dennis/polygon/GCC_tm...(no debugging symbols found)...done.
(gdb) b printf
Breakpoint 1 at 0x8048330
(gdb) run
Starting program: /home/dennis/polygon/GCC_tm
. , , time.h:
21.8: time.h
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
, :
4 date . , , GDB,
369
21. 21.
0x00000025 37 tm_sec
0x0000000a 10 tm_min
0x00000012 18 tm_hour
0x00000002 2 tm_mday
0x00000005 5 tm_mon
0x00000072 114 tm_year
0x00000001 1 tm_wday
0x00000098 152 tm_yday
0x00000001 1 tm_isdst
SYSTEMTIME (21.1 (. 362)), , ,
, , tm_wday, tm_yday, tm_isdst.
21.3.2. ARM
PUSH {LR}
MOVS R0, #0 ; timer
SUB SP, SP, #0x34
BL time
STR R0, [SP,#0x38+timer]
MOV R1, SP ; tp
ADD R0, SP, #0x38+timer ; timer
BL localtime_r
LDR R1, =0x76C
LDR R0, [SP,#0x38+var_24]
ADDS R1, R0, R1
ADR R0, aYearD ; "Year: %d\n"
BL __2printf
LDR R1, [SP,#0x38+var_28]
ADR R0, aMonthD ; "Month: %d\n"
BL __2printf
LDR R1, [SP,#0x38+var_2C]
ADR R0, aDayD ; "Day: %d\n"
BL __2printf
LDR R1, [SP,#0x38+var_30]
ADR R0, aHourD ; "Hour: %d\n"
BL __2printf
LDR R1, [SP,#0x38+var_34]
ADR R0, aMinutesD ; "Minutes: %d\n"
BL __2printf
LDR R1, [SP,#0x38+var_38]
ADR R0, aSecondsD ; "Seconds: %d\n"
BL __2printf
ADD SP, SP, #0x34
POP {PC}
370
21. 21.
21.10: Xcode 4.6.3 (LLVM) ( Thumb-2)
var_38 = 0x38
var_34 = 0x34
PUSH {R7,LR}
MOV R7, SP
SUB SP, SP, #0x30
MOVS R0, #0 ; time_t *
BLX _time
ADD R1, SP, #0x38+var_34 ; struct tm *
STR R0, [SP,#0x38+var_38]
MOV R0, SP ; time_t *
BLX _localtime_r
LDR R1, [SP,#0x38+var_34.tm_year]
MOV R0, 0xF44 ; "Year: %d\n"
ADD R0, PC ; char *
ADDW R1, R1, #0x76C
BLX _printf
LDR R1, [SP,#0x38+var_34.tm_mon]
MOV R0, 0xF3A ; "Month: %d\n"
ADD R0, PC ; char *
BLX _printf
LDR R1, [SP,#0x38+var_34.tm_mday]
MOV R0, 0xF35 ; "Day: %d\n"
ADD R0, PC ; char *
BLX _printf
LDR R1, [SP,#0x38+var_34.tm_hour]
MOV R0, 0xF2E ; "Hour: %d\n"
ADD R0, PC ; char *
BLX _printf
LDR R1, [SP,#0x38+var_34.tm_min]
MOV R0, 0xF28 ; "Minutes: %d\n"
ADD R0, PC ; char *
BLX _printf
LDR R1, [SP,#0x38+var_34]
MOV R0, 0xF25 ; "Seconds: %d\n"
ADD R0, PC ; char *
BLX _printf
ADD SP, SP, #0x30
POP {R7,PC}
...
21.3.3. MIPS
371
21. 21.
8 minutes = 0x30
9 hour = 0x2C
10 day = 0x28
11 month = 0x24
12 year = 0x20
13 var_4 = 4
14
15 lui $gp, (__gnu_local_gp >> 16)
16 addiu $sp, 0x50
17 la $gp, (__gnu_local_gp & 0xFFFF)
18 sw $ra, 0x50+var_4($sp)
19 sw $gp, 0x50+var_40($sp)
20 lw $t9, (time & 0xFFFF)($gp)
21 or $at, $zero ; load delay slot, NOP
22 jalr $t9
23 move $a0, $zero ; branch delay slot, NOP
24 lw $gp, 0x50+var_40($sp)
25 addiu $a0, $sp, 0x50+var_38
26 lw $t9, (localtime_r & 0xFFFF)($gp)
27 addiu $a1, $sp, 0x50+seconds
28 jalr $t9
29 sw $v0, 0x50+var_38($sp) ; branch delay slot
30 lw $gp, 0x50+var_40($sp)
31 lw $a1, 0x50+year($sp)
32 lw $t9, (printf & 0xFFFF)($gp)
33 la $a0, $LC0 # "Year: %d\n"
34 jalr $t9
35 addiu $a1, 1900 ; branch delay slot
36 lw $gp, 0x50+var_40($sp)
37 lw $a1, 0x50+month($sp)
38 lw $t9, (printf & 0xFFFF)($gp)
39 lui $a0, ($LC1 >> 16) # "Month: %d\n"
40 jalr $t9
41 la $a0, ($LC1 & 0xFFFF) # "Month: %d\n" ; branch delay slot
42 lw $gp, 0x50+var_40($sp)
43 lw $a1, 0x50+day($sp)
44 lw $t9, (printf & 0xFFFF)($gp)
45 lui $a0, ($LC2 >> 16) # "Day: %d\n"
46 jalr $t9
47 la $a0, ($LC2 & 0xFFFF) # "Day: %d\n" ; branch delay slot
48 lw $gp, 0x50+var_40($sp)
49 lw $a1, 0x50+hour($sp)
50 lw $t9, (printf & 0xFFFF)($gp)
51 lui $a0, ($LC3 >> 16) # "Hour: %d\n"
52 jalr $t9
53 la $a0, ($LC3 & 0xFFFF) # "Hour: %d\n" ; branch delay slot
54 lw $gp, 0x50+var_40($sp)
55 lw $a1, 0x50+minutes($sp)
56 lw $t9, (printf & 0xFFFF)($gp)
57 lui $a0, ($LC4 >> 16) # "Minutes: %d\n"
58 jalr $t9
59 la $a0, ($LC4 & 0xFFFF) # "Minutes: %d\n" ; branch delay slot
60 lw $gp, 0x50+var_40($sp)
61 lw $a1, 0x50+seconds($sp)
62 lw $t9, (printf & 0xFFFF)($gp)
63 lui $a0, ($LC5 >> 16) # "Seconds: %d\n"
64 jalr $t9
65 la $a0, ($LC5 & 0xFFFF) # "Seconds: %d\n" ; branch delay slot
66 lw $ra, 0x50+var_4($sp)
67 or $at, $zero ; load delay slot, NOP
68 jr $ra
69 addiu $sp, 0x50
70
71 $LC0: .ascii "Year: %d\n"<0>
72 $LC1: .ascii "Month: %d\n"<0>
73 $LC2: .ascii "Day: %d\n"<0>
74 $LC3: .ascii "Hour: %d\n"<0>
75 $LC4: .ascii "Minutes: %d\n"<0>
76 $LC5: .ascii "Seconds: %d\n"<0>
372
21. 21.
, branch delay slot- . , 35 addiu $a1, 1900,
1900 . JALR 34, -
.
21.3.4.
, ,
, tm : .21.8.
#include <stdio.h>
#include <time.h>
void main()
{
int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday, tm_yday, tm_isdst;
time_t unix_time;
unix_time=time(NULL);
, :
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 30h
call __main
mov [esp+30h+var_30], 0 ; arg 0
call time
mov [esp+30h+unix_time], eax
lea eax, [esp+30h+tm_sec]
mov [esp+30h+var_2C], eax
lea eax, [esp+30h+unix_time]
mov [esp+30h+var_30], eax
call localtime_r
373
21. 21.
mov eax, [esp+30h+tm_year]
add eax, 1900
mov [esp+30h+var_2C], eax
mov [esp+30h+var_30], offset aYearD ; "Year: %d\n"
call printf
mov eax, [esp+30h+tm_mon]
mov [esp+30h+var_2C], eax
mov [esp+30h+var_30], offset aMonthD ; "Month: %d\n"
call printf
mov eax, [esp+30h+tm_mday]
mov [esp+30h+var_2C], eax
mov [esp+30h+var_30], offset aDayD ; "Day: %d\n"
call printf
mov eax, [esp+30h+tm_hour]
mov [esp+30h+var_2C], eax
mov [esp+30h+var_30], offset aHourD ; "Hour: %d\n"
call printf
mov eax, [esp+30h+tm_min]
mov [esp+30h+var_2C], eax
mov [esp+30h+var_30], offset aMinutesD ; "Minutes: %d\n"
call printf
mov eax, [esp+30h+tm_sec]
mov [esp+30h+var_2C], eax
mov [esp+30h+var_30], offset aSecondsD ; "Seconds: %d\n"
call printf
leave
retn
main endp
, ,
.
. , . , -
, . ,
.
, - , tm_year, tm_mon, tm_mday, tm_hour,
tm_min, tm_sec, . , -
localtime_r().
, int. ,
16 (WORD), SYSTEMTIME GetSystemTime()
( 32- ). :
(21.4 (. 377)).
, , . , -
, . , -,
( 1972) [Rit93].
: , .
21.3.5. 32-
#include <stdio.h>
#include <time.h>
void main()
{
struct tm t;
time_t unix_time;
int i;
unix_time=time(NULL);
374
21. 21.
printf ("0x%08X (%d)\n", tmp, tmp);
};
};
, : 21.8 (. 369).
:
: , .
.
, , .
, ( 1)
.
375
21. 21.
21.3.6.
. (cast) :
#include <stdio.h>
#include <time.h>
void main()
{
struct tm t;
time_t unix_time;
int i, j;
unix_time=time(NULL);
23:51:45 26-July-2014 5 . ,
(21.3.5 (. 375)), , , little-endian (31 (. 473)).
loc_804840A:
movzx eax, byte ptr [esi+ebx] ;
add ebx, 1 ; j=j+1
mov dword ptr [esp+4], offset a0x02x ; "0x%02X "
mov dword ptr [esp], 1
mov [esp+8], eax ; printf()
5 . .
376
21. 21.
call ___printf_chk
cmp ebx, 4
jnz short loc_804840A
; (CR)
mov dword ptr [esp], 0Ah ; c
add esi, 4
call _putchar
cmp esi, edi ; ?
jnz short loc_8048408 ; j=0
lea esp, [ebp0Ch]
pop ebx
pop esi
pop edi
pop ebp
retn
main endp
21.4.
, 6 .
:
#include <stdio.h>
struct s
{
char a;
int b;
char c;
int d;
};
void f(struct s s)
{
printf ("a=%d; b=%d; c=%d; d=%d\n", s.a, s.b, s.c, s.d);
};
int main()
{
struct s tmp;
tmp.a=1;
tmp.b=2;
tmp.c=3;
tmp.d=4;
f(tmp);
};
, char ( ) int ( 4 ).
21.4.1. x86
377
21. 21.
10 sub esp, 16 ;
11 mov eax, esp
12 mov ecx, DWORD PTR _tmp$[ebp] ;
13 mov DWORD PTR [eax], ecx
14 mov edx, DWORD PTR _tmp$[ebp+4]
15 mov DWORD PTR [eax+4], edx
16 mov ecx, DWORD PTR _tmp$[ebp+8]
17 mov DWORD PTR [eax+8], ecx
18 mov edx, DWORD PTR _tmp$[ebp+12]
19 mov DWORD PTR [eax+12], edx
20 call _f
21 add esp, 16
22 xor eax, eax
23 mov esp, ebp
24 pop ebp
25 ret 0
26 _main ENDP
27
28 _s$ = 8 ; size = 16
29 ?f@@YAXUs@@@Z PROC ; f
30 push ebp
31 mov ebp, esp
32 mov eax, DWORD PTR _s$[ebp+12]
33 push eax
34 movsx ecx, BYTE PTR _s$[ebp+8]
35 push ecx
36 mov edx, DWORD PTR _s$[ebp+4]
37 push edx
38 movsx eax, BYTE PTR _s$[ebp]
39 push eax
40 push OFFSET $SG3842
41 call _printf
42 add esp, 20
43 pop ebp
44 ret 0
45 ?f@@YAXUs@@@Z ENDP ; f
46 _TEXT ENDS
, , , ,
( 10, 4 , , 12 19),
( ). , ,
f() . , main() .
/++, , .
4- . char
4 int. ?
.
.
(/Zp1) (/Zp[n] pack structures on n-byte boundary).
378
21. 21.
18 add esp, 12
19 xor eax, eax
20 mov esp, ebp
21 pop ebp
22 ret 0
23 _main ENDP
24
25 _TEXT SEGMENT
26 _s$ = 8 ; size = 10
27 ?f@@YAXUs@@@Z PROC ; f
28 push ebp
29 mov ebp, esp
30 mov eax, DWORD PTR _s$[ebp+6]
31 push eax
32 movsx ecx, BYTE PTR _s$[ebp+5]
33 push ecx
34 mov edx, DWORD PTR _s$[ebp+1]
35 push edx
36 movsx eax, BYTE PTR _s$[ebp]
37 push eax
38 push OFFSET $SG3842
39 call _printf
40 add esp, 20
41 pop ebp
42 ret 0
43 ?f@@YAXUs@@@Z ENDP ; f
10 char . ? .
, .
main(). , 10 , MOV. 4?
, 10 3 MOV, 32-
4 MOV. , MOV
memcpy(), , ,
memcpy() , : 43.1.5 (. 527).
, ,
.
MSVC /Zp, , ,
#pragma pack, . MSVC7 GCC8 .
SYSTEMTIME, 16- .
?
WinNT.h :
21.18: WinNT.h
#include "pshpack1.h"
21.19: WinNT.h
#include "pshpack4.h" // 4 byte packing is the default
PshPack1.h :
21.20: PshPack1.h
#if ! (defined(lint) || defined(RC_INVOKED))
#if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
#pragma warning(disable:4103)
#if !(defined( MIDL_PASS )) || defined( __midl )
#pragma pack(push,1)
#else
#pragma pack(1)
#endif
#else
7 MSDN: Working with Packing Structures
8 Structure-Packing Pragmas
379
21. 21.
#pragma pack(1)
#endif
#endif /* ! (defined(lint) || defined(RC_INVOKED)) */
, , #pragma pack .
380
21. 21.
OllyDbg +
OllyDbg , (4 ) :
381
21. 21.
OllyDbg + 1
: 4 10
21.4.2. ARM
.text:00000280 f
.text:00000280
.text:00000280 var_18 = 0x18
.text:00000280 a = 0x14
.text:00000280 b = 0x10
.text:00000280 c = 0xC
.text:00000280 d = 8
.text:00000280
.text:00000280 0F B5 PUSH {R0R3,LR}
.text:00000282 81 B0 SUB SP, SP, #4
.text:00000284 04 98 LDR R0, [SP,#16] ; d
.text:00000286 02 9A LDR R2, [SP,#8] ; b
.text:00000288 00 90 STR R0, [SP]
.text:0000028A 68 46 MOV R0, SP
.text:0000028C 03 7B LDRB R3, [R0,#12] ; c
.text:0000028E 01 79 LDRB R1, [R0,#4] ; a
.text:00000290 59 A0 ADR R0, aADBDCDDD ; "a=%d; b=%d; c=%d; d=%d\n"
.text:00000292 05 F0 AD FF BL __2printf
.text:00000296 D2 E6 B exit
, , , ARM 4
, R0-R3.
LDRB 32- .
MOVSX x86. a c .
, , ! ,
, , , , (,
5 (5 4 = 0x14)). , ( ). -
, , , , . Keil
, , - . 4 , 2.
382
21. 21.
ARM + Xcode 4.6.3 (LLVM) ( Thumb-2)
PUSH {R7,LR}
MOV R7, SP
SUB SP, SP, #4
MOV R9, R1 ; b
MOV R1, R0 ; a
MOVW R0, #0xF10 ; "a=%d; b=%d; c=%d; d=%d\n"
SXTB R1, R1 ; prepare a
MOVT.W R0, #0
STR R3, [SP,#0xC+var_C] ; place d to stack for printf()
ADD R0, PC ; formatstring
SXTB R3, R2 ; prepare c
MOV R2, R9 ; b
BLX _printf
ADD SP, SP, #4
POP {R7,PC}
21.4.3. MIPS
383
21. 21.
42 $LC0: .ascii "a=%d; b=%d; c=%d; d=%d\n"<0>
21.4.4. -
( )
. , f() :
void f(char a, int b, char c, int d)
{
printf ("a=%d; b=%d; c=%d; d=%d\n", a, b, c, d);
};
21.5.
, , ?
#include <stdio.h>
struct inner_struct
{
int a;
int b;
};
struct outer_struct
{
char a;
int b;
struct inner_struct c;
char d;
int e;
};
int main()
{
struct outer_struct s;
s.a=1;
s.b=2;
s.c.a=100;
s.c.b=101;
s.d=3;
s.e=4;
f(s);
};
384
21. 21.
_TEXT SEGMENT
_s$ = 8
_f PROC
mov eax, DWORD PTR _s$[esp+16]
movsx ecx, BYTE PTR _s$[esp+12]
mov edx, DWORD PTR _s$[esp+8]
push eax
mov eax, DWORD PTR _s$[esp+8]
push ecx
mov ecx, DWORD PTR _s$[esp+8]
push edx
movsx edx, BYTE PTR _s$[esp+8]
push eax
push ecx
push edx
push OFFSET $SG2802 ; 'a=%d; b=%d; c.a=%d; c.b=%d; d=%d; e=%d'
call _printf
add esp, 28
ret 0
_f ENDP
_s$ = 24
_main PROC
sub esp, 24
push ebx
push esi
push edi
mov ecx, 2
sub esp, 24
mov eax, esp
mov BYTE PTR _s$[esp+60], 1
mov ebx, DWORD PTR _s$[esp+60]
mov DWORD PTR [eax], ebx
mov DWORD PTR [eax+4], ecx
lea edx, DWORD PTR [ecx+98]
lea esi, DWORD PTR [ecx+99]
lea edi, DWORD PTR [ecx+2]
mov DWORD PTR [eax+8], edx
mov BYTE PTR _s$[esp+76], 3
mov ecx, DWORD PTR _s$[esp+76]
mov DWORD PTR [eax+12], esi
mov DWORD PTR [eax+16], ecx
mov DWORD PTR [eax+20], edi
call _f
add esp, 24
pop edi
pop esi
xor eax, eax
pop ebx
add esp, 24
ret 0
_main ENDP
, , ,
- ! , , , -
, .
, struct inner_struct c; struct inner_struct *c; ( -
), .
385
21. 21.
21.5.1. OllyDbg
OllyDbg outer_struct :
:
(outer_struct.a) () 1 + 3 ;
(outer_struct.b) (32- ) 2;
(inner_struct.a) (32- ) 0x64 (100);
(inner_struct.b) (32- ) 0x65 (101);
(outer_struct.d) () 3 + 3 ;
(outer_struct.e) (32- ) 4.
21.6.
21.6.1. CPUID
/++ , .
. , bool . , ,
.
CPUID9 . ,
.
EAX 1, CPUID EAX -
:
3:0 (4 ) Stepping
7:4 (4 ) Model
11:8 (4 ) Family
13:12 (2 ) Processor Type
19:16 (4 ) Extended Model
27:20 (8 ) Extended Family
MSVC 2010 CPUID, GCC 4.4.1 . GCC ,
10 .
#include <stdio.h>
#ifdef __GNUC__
9 wikipedia
10 GCC
386
21. 21.
static inline void cpuid(int code, int *a, int *b, int *c, int *d) {
asm volatile("cpuid":"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d):"a"(code));
}
#endif
#ifdef _MSC_VER
#include <intrin.h>
#endif
struct CPUID_1_EAX
{
unsigned int stepping:4;
unsigned int model:4;
unsigned int family_id:4;
unsigned int processor_type:2;
unsigned int reserved1:2;
unsigned int extended_model_id:4;
unsigned int extended_family_id:8;
unsigned int reserved2:4;
};
int main()
{
struct CPUID_1_EAX *tmp;
int b[4];
#ifdef _MSC_VER
__cpuid(b,1);
#endif
#ifdef __GNUC__
cpuid (1, &b[0], &b[1], &b[2], &b[3]);
#endif
return 0;
};
MSVC
387
21. 21.
mov DWORD PTR [esi+12], edx
shr esi, 20
and esi, 255
push esi
push OFFSET $SG15440 ; 'extended_family_id=%d', 0aH, 00H
call _printf
add esp, 48
pop esi
add esp, 16
ret 0
_main ENDP
SHR EAX , , ,
.
AND , , ,
EAX, .
388
21. 21.
MSVC + OllyDbg
. 21.7: OllyDbg:
GCC
389
21. 21.
mov esi, 1
push ebx
mov eax, esi
sub esp, 18h
cpuid
mov esi, eax
and eax, 0Fh
mov [esp+8], eax
mov dword ptr [esp+4], offset aSteppingD ; "stepping=%d\n"
mov dword ptr [esp], 1
call ___printf_chk
mov eax, esi
shr eax, 4
and eax, 0Fh
mov [esp+8], eax
mov dword ptr [esp+4], offset aModelD ; "model=%d\n"
mov dword ptr [esp], 1
call ___printf_chk
mov eax, esi
shr eax, 8
and eax, 0Fh
mov [esp+8], eax
mov dword ptr [esp+4], offset aFamily_idD ; "family_id=%d\n"
mov dword ptr [esp], 1
call ___printf_chk
mov eax, esi
shr eax, 0Ch
and eax, 3
mov [esp+8], eax
mov dword ptr [esp+4], offset aProcessor_type ; "processor_type=%d\n"
mov dword ptr [esp], 1
call ___printf_chk
mov eax, esi
shr eax, 10h
shr esi, 14h
and eax, 0Fh
and esi, 0FFh
mov [esp+8], eax
mov dword ptr [esp+4], offset aExtended_model ; "extended_model_id=%d\n"
mov dword ptr [esp], 1
call ___printf_chk
mov [esp+8], esi
mov dword ptr [esp+4], offset unk_80486D0
mov dword ptr [esp], 1
call ___printf_chk
add esp, 18h
xor eax, eax
pop ebx
pop esi
mov esp, ebp
pop ebp
retn
main endp
, . , GCC -
extended_model_id extended_family_id ,
printf().
21.6.2. oat
31 30 23 22 0
( S )
390
21. 21.
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <memory.h>
struct float_as_struct
{
unsigned int fraction : 23; //
unsigned int exponent : 8; // + 0x3FF
unsigned int sign : 1; //
};
float f(float )
{
float f=;
struct float_as_struct t;
t.sign=1; //
t.exponent=t.exponent+2; // d 2n (n 2)
return f;
};
int main()
{
printf ("%f\n", f(1.234));
};
float_as_struct oat, 4 32 .
, ,
22 , 4.
MSVC 2008 :
21.27: MSVC 2008
_t$ = 8 ; size = 4
_f$ = 4 ; size = 4
__in$ = 8 ; size = 4
?f@@YAMM@Z PROC ; f
push ebp
mov ebp, esp
sub esp, 8
push 4
lea eax, DWORD PTR _f$[ebp]
push eax
lea ecx, DWORD PTR _t$[ebp]
push ecx
call _memcpy
add esp, 12
391
21. 21.
shl eax, 23 ; 00000017H 30:23
mov ecx, DWORD PTR _t$[ebp]
and ecx, 2139095041 ; 807fffffH
;
or ecx, eax
mov DWORD PTR _t$[ebp], ecx
push 4
lea edx, DWORD PTR _t$[ebp]
push edx
lea eax, DWORD PTR _f$[ebp]
push eax
call _memcpy
add esp, 12
. /Ox memcpy(),
f. .
GCC 4.4.1 -O3?
push ebp
mov ebp, esp
sub esp, 4
mov eax, [ebp+arg_0]
or eax, 80000000h ;
mov edx, eax
and eax, 807FFFFFh ; EAX
shr edx, 23 ;
add edx, 2 ; 2
movzx edx, dl ; 7:0 EAX 0
shl edx, 23 ;
or eax, edx ;
mov [ebp+var_4], eax
fld [ebp+var_4]
leave
retn
_Z1ff endp
public main
main proc near
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
fld ds:dword_8048614 ; 4.936
fstp qword ptr [esp+8]
mov dword ptr [esp+4], offset asc_8048610 ; "%f\n"
mov dword ptr [esp], 1
call ___printf_chk
xor eax, eax
leave
retn
main endp
392
21. 21.
, f() . , , , -
, GCC f(1.234)
printf()!
21.7.
21.7.1. #1
21.7.2. #2
- -. ,
. .
_s$ = 8
_f PROC
push esi
mov esi, DWORD PTR _s$[esp]
cmp DWORD PTR [esi], 1000
jle SHORT $LN4@f
cmp DWORD PTR [esi+4], 10
jbe SHORT $LN3@f
fld DWORD PTR [esi+8]
sub esp, 8
fmul QWORD PTR __real@407bc00000000000
fld QWORD PTR [esi+16]
fmul QWORD PTR __real@405ec00000000000
faddp ST(1), ST(0)
fstp QWORD PTR [esp]
push OFFSET $SG2802 ; '%f'
call _printf
movzx eax, BYTE PTR [esi+25]
movsx ecx, BYTE PTR [esi+24]
push eax
push ecx
push OFFSET $SG2803 ; '%c, %d'
call _printf
add esp, 24
pop esi
ret 0
$LN3@f:
pop esi
mov DWORD PTR _s$[esp4], OFFSET $SG2805 ; 'error #2'
jmp _printf
$LN4@f:
pop esi
mov DWORD PTR _s$[esp4], OFFSET $SG2807 ; 'error #1'
jmp _printf
_f ENDP
393
21. 21.
21.30: Keil 6/2013 ( ARM)
f PROC
PUSH {r4r6,lr}
MOV r4,r0
LDR r0,[r0,#0]
CMP r0,#0x3e8
ADRLE r0,|L0.140|
BLE |L0.132|
LDR r0,[r4,#4]
CMP r0,#0xa
ADRLS r0,|L0.152|
BLS |L0.132|
ADD r0,r4,#0x10
LDM r0,{r0,r1}
LDR r3,|L0.164|
MOV r2,#0
BL __aeabi_dmul
MOV r5,r0
MOV r6,r1
LDR r0,[r4,#8]
LDR r1,|L0.168|
BL __aeabi_fmul
BL __aeabi_f2d
MOV r2,r5
MOV r3,r6
BL __aeabi_dadd
MOV r2,r0
MOV r3,r1
ADR r0,|L0.172|
BL __2printf
LDRB r2,[r4,#0x19]
LDRB r1,[r4,#0x18]
POP {r4r6,lr}
ADR r0,|L0.176|
B __2printf
|L0.132|
POP {r4r6,lr}
B __2printf
ENDP
|L0.140|
DCB "error #1\n",0
DCB 0
DCB 0
|L0.152|
DCB "error #2\n",0
DCB 0
DCB 0
|L0.164|
DCD 0x405ec000
|L0.168|
DCD 0x43de0000
|L0.172|
DCB "%f\n",0
|L0.176|
DCB "%c, %d\n",0
394
21. 21.
ADD r0,r4,#0x10
LDM r0,{r0,r1}
LDR r3,|L0.164|
MOV r2,#0
BL __aeabi_dmul
MOV r5,r0
MOV r6,r1
LDR r0,[r4,#8]
LDR r1,|L0.168|
BL __aeabi_fmul
BL __aeabi_f2d
MOV r2,r5
MOV r3,r6
BL __aeabi_dadd
MOV r2,r0
MOV r3,r1
ADR r0,|L0.172|
BL __2printf
LDRB r2,[r4,#0x19]
LDRB r1,[r4,#0x18]
POP {r4r6,lr}
ADR r0,|L0.176|
B __2printf
|L0.132|
POP {r4r6,lr}
B __2printf
ENDP
|L0.140|
DCB "error #1\n",0
DCB 0
DCB 0
|L0.152|
DCB "error #2\n",0
DCB 0
DCB 0
|L0.164|
DCD 0x405ec000
|L0.168|
DCD 0x43de0000
|L0.172|
DCB "%f\n",0
|L0.176|
DCB "%c, %d\n",0
395
21. 21.
adrp x0, .LC3
ldrb w2, [x19,25]
add x0, x0, :lo12:.LC3
ldr x19, [sp,16]
ldp x29, x30, [sp], 32
b printf
.L3:
ldr x19, [sp,16]
adrp x0, .LC4
ldp x29, x30, [sp], 32
add x0, x0, :lo12:.LC4
b puts
.L2:
ldr x19, [sp,16]
adrp x0, .LC5
ldp x29, x30, [sp], 32
add x0, x0, :lo12:.LC5
b puts
.size f, .f
.LC1:
.word 1138622464
.LC2:
.word 0
.word 1079951360
.LC0:
.string "%f\n"
.LC3:
.string "%c, %d\n"
.LC4:
.string "error #2"
.LC5:
.string "error #1"
var_10 = 0x10
var_8 = 8
var_4 = 4
396
21. 21.
mfc1 $a2, $f5
mfc1 $a3, $f4
jalr $t9
la $a0, ($LC0 & 0xFFFF) # "%f\n"
lw $gp, 0x20+var_10($sp)
lbu $a2, 0x19($s0)
lb $a1, 0x18($s0)
lui $a0, ($LC3 >> 16) # "%c, %d\n"
lw $t9, (printf & 0xFFFF)($gp)
lw $ra, 0x20+var_4($sp)
lw $s0, 0x20+var_8($sp)
la $a0, ($LC3 & 0xFFFF) # "%c, %d\n"
jr $t9
addiu $sp, 0x20
loc_AC: # CODE XREF: f+38
lui $a0, ($LC4 >> 16) # "error #2"
lw $t9, (puts & 0xFFFF)($gp)
lw $ra, 0x20+var_4($sp)
lw $s0, 0x20+var_8($sp)
la $a0, ($LC4 & 0xFFFF) # "error #2"
jr $t9
addiu $sp, 0x20
loc_C8: # CODE XREF: f+24
lui $a0, ($LC5 >> 16) # "error #1"
lw $t9, (puts & 0xFFFF)($gp)
lw $ra, 0x20+var_4($sp)
lw $s0, 0x20+var_8($sp)
la $a0, ($LC5 & 0xFFFF) # "error #1"
jr $t9
addiu $sp, 0x20
.data # .rodata.cst4
$LC1: .word 0x43DE0000
.data # .rodata.cst8
$LC2: .word 0x405EC000
dword_134: .word 0
: G.1.14 (. 991).
397
22. (UNION) 22. (UNION)
22
(union)
union /++ ( ) -
.
22.1.
0 1,
Mersenne twister. 32- DWORD.
oat RAND_MAX (0xFFFFFFFF ) 0 1.
, . FPU.
?
: , . -
, !
( ),
01111111 .
, 0 ( ), .
1 2, .
1 , 32-
. UNIX.
, oat union /++
-. , union oat
uint32_t. , , .
, : 20 (. 356).
.
#include <stdio.h>
#include <stdint.h>
#include <time.h>
// , - PRNG
// Numerical Recipes
const uint32_t RNG_a=1664525;
const uint32_t RNG_c=1013904223;
uint32_t RNG_state; //
void my_srand(uint32_t i)
{
RNG_state=i;
};
uint32_t my_rand()
{
RNG_state=RNG_state*RNG_a+RNG_c;
return RNG_state;
1 : http://go.yurichev.com/17308
398
22. (UNION) 22. (UNION)
};
// - FPU PRNG:
union uint32_t_float
{
uint32_t i;
float f;
};
float float_rand()
{
union uint32_t_float tmp;
tmp.i=my_rand() & 0x007fffff | 0x3F800000;
return tmp.f1;
};
//
int main()
{
my_srand(time(NULL)); // PRNG
return 0;
};
22.1.1. x86
__real@3ff0000000000000 DQ 03ff0000000000000r ; 1
tv130 = 4
_tmp$ = 4
?float_rand@@YAMXZ PROC
push ecx
call ?my_rand@@YAIXZ
; EAX=
and eax, 8388607 ; 007fffffH
or eax, 1065353216 ; 3f800000H
; EAX= & 0x007fffff | 0x3f800000
;
mov DWORD PTR _tmp$[esp+4], eax
; :
fld DWORD PTR _tmp$[esp+4]
; 1.0:
fsub QWORD PTR __real@3ff0000000000000
;
fstp DWORD PTR tv130[esp+4] ; \
fld DWORD PTR tv130[esp+4] ; /
pop ecx
ret 0
?float_rand@@YAMXZ ENDP
_main PROC
push esi
xor eax, eax
call _time
push eax
call ?my_srand@@YAXI@Z
add esp, 4
mov esi, 100
$LL3@main:
399
22. (UNION) 22. (UNION)
call ?float_rand@@YAMXZ
sub esp, 8
fstp QWORD PTR [esp]
push OFFSET $SG4238
call _printf
add esp, 12
dec esi
jne SHORT $LL3@main
xor eax, eax
pop esi
ret 0
_main ENDP
, ++, ++,
: 51.1.1 (. 564).
MSVC 2012, SIMD- FPU, :
27.5 (. 462).
22.1.2. MIPS
var_10 = 0x10
var_4 = 4
main:
var_18 = 0x18
var_10 = 0x10
var_C = 0xC
var_8 = 8
var_4 = 4
400
22. (UNION) 22. (UNION)
sw $ra, 0x28+var_4($sp)
sw $s2, 0x28+var_8($sp)
sw $s1, 0x28+var_C($sp)
sw $s0, 0x28+var_10($sp)
sw $gp, 0x28+var_18($sp)
lw $t9, (time & 0xFFFF)($gp)
or $at, $zero ; load delay slot, NOP
jalr $t9
move $a0, $zero ; branch delay slot
lui $s2, ($LC1 >> 16) # "%f\n"
move $a0, $v0
la $s2, ($LC1 & 0xFFFF) # "%f\n"
move $s0, $zero
jal my_srand
li $s1, 0x64 # 'd' ; branch delay slot
loc_104:
jal float_rand
addiu $s0, 1
lw $gp, 0x28+var_18($sp)
; float_rand() double ( printf()):
cvt.d.s $f2, $f0
lw $t9, (printf & 0xFFFF)($gp)
mfc1 $a3, $f2
mfc1 $a2, $f3
jalr $t9
move $a0, $s2
bne $s0, $s1, loc_104
move $v0, $zero
lw $ra, 0x28+var_4($sp)
lw $s2, 0x28+var_8($sp)
lw $s1, 0x28+var_C($sp)
lw $s0, 0x28+var_10($sp)
jr $ra
addiu $sp, 0x28 ; branch delay slot
- LUI, . :
17.5.6 (. 228).
main
STMFD SP!, {R4,LR}
MOV R0, #0
BL time
401
22. (UNION) 22. (UNION)
BL my_srand
MOV R4, #0x64 ; 'd'
loc_78
BL float_rand
; S0=
LDR R0, =aF ; "%f"
; float double ( printf()):
FCVTDS D7, S0
; D7 R2/R3 ( printf()):
FMRRD R2, R3, D7
BL printf
SUBS R4, R4, #1
BNE loc_78
MOV R0, R4
LDMFD SP!, {R4,PC}
aF DCB "%f",0xA,0
00000000 <main>:
0: e92d4010 push {r4, lr}
4: e3a00000 mov r0, #0
8: ebfffffe bl 0 <time>
c: ebfffffe bl 0 <main>
10: e3a04064 mov r4, #100 ; 0x64
14: ebfffffe bl 38 <main+0x38>
18: e59f0018 ldr r0, [pc, #24] ; 38 <main+0x38>
1c: eeb77ac0 vcvt.f64.f32 d7, s0
20: ec532b17 vmov r2, r3, d7
24: ebfffffe bl 0 <printf>
28: e2544001 subs r4, r4, #1
2c: 1afffff8 bne 14 <main+0x14>
30: e1a00004 mov r0, r4
34: e8bd8010 pop {r4, pc}
38: 00000000 andeq r0, r0, r0
22.2.
, FPU 2 .
, . 223 = 1.19e 07 oat 252 = 2.22e 16 double.
, :
#include <stdio.h>
#include <stdint.h>
union uint_float
2 .
402
22. (UNION) 22. (UNION)
{
uint32_t i;
float f;
};
void main()
{
printf ("%g\n", calculate_machine_epsilon(1.234567));
};
IEEE 754 -
. starting_value + machine_epsilon,
( ) ,
(oat).
union IEEE 754 . -
1 1 , , , ,
.
22.2.1. x86
FST : (
v , ).
INC, .
FPU 32- IEEE 754, FSUBR ST0.
FSTP/FLD , .
22.2.2. ARM64
64-:
#include <stdio.h>
#include <stdint.h>
typedef union
{
uint64_t i;
double d;
} uint_double;
403
22. (UNION) 22. (UNION)
v.d=start;
v.i++;
return v.dstart;
}
void main()
{
printf ("%g\n", calculate_machine_epsilon(1.234567));
};
22.2.3. MIPS
22.2.4.
, - ,
, IEEE 754 union /++.
22.3.
oat ,
.
404
22. (UNION) 22. (UNION)
*
* .
*/
, , .
1 . , , -
x
Quake III Arena.
Wikipedia: http://go.yurichev.com/17361.
405
23. 23.
23
, , , ,
.
.. callback- 1 .
:
qsort()2 , atexit()3 ;
*NIX 4 ;
: CreateThread() (win32), pthread_create() (POSIX);
win32, EnumChildWindows()5 .
Linux, , callback-: http:
//go.yurichev.com/17076
GCC callback-: http://go.yurichev.com/17077
dwm Linux,
-. - , , :
GitHub. , switch().
, qsort() . ,
, , qsort()
.
:
int (*compare)(const void *, const void *)
, :
1 /* ex3 Sorting ints with qsort */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 int comp(const void * _a, const void * _b)
7 {
8 const int *a=(const int *)_a;
9 const int *b=(const int *)_b;
10
11 if (*a==*b)
12 return 0;
13 else
14 if (*a < *b)
15 return 1;
16 else
17 return 1;
18 }
1 wikipedia
2 wikipedia
3 http://go.yurichev.com/17073
4 wikipedia
5 MSDN
406
23. 23.
19
20 int main(int argc, char* argv[])
21 {
22 int numbers[10]={1892,45,200,98,4087,5,12345,1087,88,100000};
23 int i;
24
25 /* Sort the array */
26 qsort(numbers,10,sizeof(int),comp) ;
27 for (i=0;i<9;i++)
28 printf("Number = %d\n",numbers[ i ]) ;
29 return 0;
30 }
23.1. MSVC
MSVC 2010 ( ) /Ox :
23.1: MSVC 2010: /GS- /MD
__a$ = 8 ; size = 4
__b$ = 12 ; size = 4
_comp PROC
mov eax, DWORD PTR __a$[esp4]
mov ecx, DWORD PTR __b$[esp4]
mov eax, DWORD PTR [eax]
mov ecx, DWORD PTR [ecx]
cmp eax, ecx
jne SHORT $LN4@comp
xor eax, eax
ret 0
$LN4@comp:
xor edx, edx
cmp eax, ecx
setge dl
lea eax, DWORD PTR [edx+edx1]
ret 0
_comp ENDP
_numbers$ = 40 ; size = 40
_argc$ = 8 ; size = 4
_argv$ = 12 ; size = 4
_main PROC
sub esp, 40 ; 00000028H
push esi
push OFFSET _comp
push 4
lea eax, DWORD PTR _numbers$[esp+52]
push 10 ; 0000000aH
push eax
mov DWORD PTR _numbers$[esp+60], 1892 ; 00000764H
mov DWORD PTR _numbers$[esp+64], 45 ; 0000002dH
mov DWORD PTR _numbers$[esp+68], 200 ; 000000c8H
mov DWORD PTR _numbers$[esp+72], 98 ; ffffff9eH
mov DWORD PTR _numbers$[esp+76], 4087 ; 00000ff7H
mov DWORD PTR _numbers$[esp+80], 5
mov DWORD PTR _numbers$[esp+84], 12345 ; ffffcfc7H
mov DWORD PTR _numbers$[esp+88], 1087 ; 0000043fH
mov DWORD PTR _numbers$[esp+92], 88 ; 00000058H
mov DWORD PTR _numbers$[esp+96], 100000 ; fffe7960H
call _qsort
add esp, 16 ; 00000010H
...
. , qsort() -
_comp, comp(), , ,
.
407
23. 23.
qsort() ?
MSVCR80.DLL ( DLL MSVC ):
23.2: MSVCR80.DLL
.text:7816CBF0 ; void __cdecl qsort(void *, unsigned int, unsigned int, int (__cdecl *)(const void *,
const void *))
.text:7816CBF0 public _qsort
.text:7816CBF0 _qsort proc near
.text:7816CBF0
.text:7816CBF0 lo = dword ptr 104h
.text:7816CBF0 hi = dword ptr 100h
.text:7816CBF0 var_FC = dword ptr 0FCh
.text:7816CBF0 stkptr = dword ptr 0F8h
.text:7816CBF0 lostk = dword ptr 0F4h
.text:7816CBF0 histk = dword ptr 7Ch
.text:7816CBF0 base = dword ptr 4
.text:7816CBF0 num = dword ptr 8
.text:7816CBF0 width = dword ptr 0Ch
.text:7816CBF0 comp = dword ptr 10h
.text:7816CBF0
.text:7816CBF0 sub esp, 100h
....
comp . , comp.
comp(). , .
. -, qsort()
, qsort(), , , ,
.
-, callback- ,
, , ,
, .
408
23. 23.
23.1.1. MSVC + OllyDbg
OllyDbg comp() .
, comp() :
, OllyDbg . , SP
RA qsort() ( , MSVCR100.DLL).
409
23. 23.
(F8) RETN F8 , qsort():
410
23. 23.
comp() :
:
PID=4336|New process 17_1.exe
(0) 17_1.exe!0x40100c
EAX=0x00000764 EBX=0x0051f7c8 ECX=0x00000005 EDX=0x00000000
ESI=0x0051f7d8 EDI=0x0051f7b4 EBP=0x0051f794 ESP=0x0051f67c
EIP=0x0028100c
FLAGS=IF
(0) 17_1.exe!0x40100c
EAX=0x00000005 EBX=0x0051f7c8 ECX=0xfffe7960 EDX=0x00000000
ESI=0x0051f7d8 EDI=0x0051f7b4 EBP=0x0051f794 ESP=0x0051f67c
EIP=0x0028100c
FLAGS=PF ZF IF
(0) 17_1.exe!0x40100c
EAX=0x00000764 EBX=0x0051f7c8 ECX=0x00000005 EDX=0x00000000
ESI=0x0051f7d8 EDI=0x0051f7b4 EBP=0x0051f794 ESP=0x0051f67c
EIP=0x0028100c
FLAGS=CF PF ZF IF
...
EAX ECX :
EAX=0x00000764 ECX=0x00000005
EAX=0x00000005 ECX=0xfffe7960
EAX=0x00000764 ECX=0x00000005
EAX=0x0000002d ECX=0x00000005
EAX=0x00000058 ECX=0x00000005
EAX=0x0000043f ECX=0x00000005
EAX=0xffffcfc7 ECX=0x00000005
EAX=0x000000c8 ECX=0x00000005
EAX=0xffffff9e ECX=0x00000005
EAX=0x00000ff7 ECX=0x00000005
EAX=0x00000ff7 ECX=0x00000005
EAX=0xffffff9e ECX=0x00000005
EAX=0xffffff9e ECX=0x00000005
EAX=0xffffcfc7 ECX=0xfffe7960
411
23. 23.
EAX=0x00000005 ECX=0xffffcfc7
EAX=0xffffff9e ECX=0x00000005
EAX=0xffffcfc7 ECX=0xfffe7960
EAX=0xffffff9e ECX=0xffffcfc7
EAX=0xffffcfc7 ECX=0xfffe7960
EAX=0x000000c8 ECX=0x00000ff7
EAX=0x0000002d ECX=0x00000ff7
EAX=0x0000043f ECX=0x00000ff7
EAX=0x00000058 ECX=0x00000ff7
EAX=0x00000764 ECX=0x00000ff7
EAX=0x000000c8 ECX=0x00000764
EAX=0x0000002d ECX=0x00000764
EAX=0x0000043f ECX=0x00000764
EAX=0x00000058 ECX=0x00000764
EAX=0x000000c8 ECX=0x00000058
EAX=0x0000002d ECX=0x000000c8
EAX=0x0000043f ECX=0x000000c8
EAX=0x000000c8 ECX=0x00000058
EAX=0x0000002d ECX=0x000000c8
EAX=0x0000002d ECX=0x00000058
34 . , 34 10-
.
412
23. 23.
23.1.3. MSVC + tracer (code coverage)
tracer
IDA.
comp():
tracer.exe l:17_1.exe bpf=17_1.exe!0x00401000,trace:cc
.idc- IDA :
(PtFuncCompare) IDA ,
qsort() .
, a b , 4, ,
32- .
, 0x401010 0x401012 ( ): -
, comp() 0, .
23.2. GCC
:
23.3: GCC
lea eax, [esp+40h+var_28]
mov [esp+40h+var_40], eax
mov [esp+40h+var_28], 764h
mov [esp+40h+var_24], 2Dh
mov [esp+40h+var_20], 0C8h
mov [esp+40h+var_1C], 0FFFFFF9Eh
mov [esp+40h+var_18], 0FF7h
mov [esp+40h+var_14], 5
mov [esp+40h+var_10], 0FFFFCFC7h
mov [esp+40h+var_C], 43Fh
mov [esp+40h+var_8], 58h
mov [esp+40h+var_4], 0FFFE7960h
mov [esp+40h+var_34], offset comp
mov [esp+40h+var_38], 4
413
23. 23.
mov [esp+40h+var_3C], 0Ah
call _qsort
comp():
public comp
comp proc near
push ebp
mov ebp, esp
mov eax, [ebp+arg_4]
mov ecx, [ebp+arg_0]
mov edx, [eax]
xor eax, eax
cmp [ecx], edx
jnz short loc_8048458
pop ebp
retn
loc_8048458:
setnl al
movzx eax, al
lea eax, [eax+eax1]
pop ebp
retn
comp endp
, (23 (. 406)),
(b) (11- ).
-g, . -
(p): ,
/ .
(bt) Glibc -
msort_with_tmp().
23.5: GDB-
dennis@ubuntuvm:~/polygon$ gcc 17_1.c g
dennis@ubuntuvm:~/polygon$ gdb ./a.out
GNU gdb (GDB) 7.6.1ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686linuxgnu".
For bug reporting instructions, please see:
6 thunk function
414
23. 23.
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dennis/polygon/a.out...done.
(gdb) b 17_1.c:11
Breakpoint 1 at 0x804845f: file 17_1.c, line 11.
(gdb) run
Starting program: /home/dennis/polygon/./a.out
, comp() (disas),
CMP (b) .
(info registers). (bt), :
comp() .
23.6: GDB-
dennis@ubuntuvm:~/polygon$ gcc 17_1.c
dennis@ubuntuvm:~/polygon$ gdb ./a.out
GNU gdb (GDB) 7.6.1ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686linuxgnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dennis/polygon/a.out...(no debugging symbols found)...done.
(gdb) set disassemblyflavor intel
(gdb) disas comp
Dump of assembler code for function comp:
0x0804844d <+0>: push ebp
0x0804844e <+1>: mov ebp,esp
0x08048450 <+3>: sub esp,0x10
0x08048453 <+6>: mov eax,DWORD PTR [ebp+0x8]
0x08048456 <+9>: mov DWORD PTR [ebp0x8],eax
0x08048459 <+12>: mov eax,DWORD PTR [ebp+0xc]
0x0804845c <+15>: mov DWORD PTR [ebp0x4],eax
415
23. 23.
0x0804845f <+18>: mov eax,DWORD PTR [ebp0x8]
0x08048462 <+21>: mov edx,DWORD PTR [eax]
0x08048464 <+23>: mov eax,DWORD PTR [ebp0x4]
0x08048467 <+26>: mov eax,DWORD PTR [eax]
0x08048469 <+28>: cmp edx,eax
0x0804846b <+30>: jne 0x8048474 <comp+39>
0x0804846d <+32>: mov eax,0x0
0x08048472 <+37>: jmp 0x804848e <comp+65>
0x08048474 <+39>: mov eax,DWORD PTR [ebp0x8]
0x08048477 <+42>: mov edx,DWORD PTR [eax]
0x08048479 <+44>: mov eax,DWORD PTR [ebp0x4]
0x0804847c <+47>: mov eax,DWORD PTR [eax]
0x0804847e <+49>: cmp edx,eax
0x08048480 <+51>: jge 0x8048489 <comp+60>
0x08048482 <+53>: mov eax,0xffffffff
0x08048487 <+58>: jmp 0x804848e <comp+65>
0x08048489 <+60>: mov eax,0x1
0x0804848e <+65>: leave
0x0804848f <+66>: ret
End of assembler dump.
(gdb) b *0x08048469
Breakpoint 1 at 0x8048469
(gdb) run
Starting program: /home/dennis/polygon/./a.out
416
23. 23.
ecx 0xbffff100 1073745664
edx 0xc8 200
ebx 0xb7fc0000 1208221696
esp 0xbfffeeb8 0xbfffeeb8
ebp 0xbfffeec8 0xbfffeec8
esi 0xbffff104 1073745660
edi 0xbffff010 1073745904
eip 0x8048469 0x8048469 <comp+28>
eflags 0x286 [ PF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) bt
#0 0x08048469 in comp ()
#1 0xb7e42872 in msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=2)
at msort.c:65
#2 0xb7e4273e in msort_with_tmp (n=2, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
#3 msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=5) at msort.c:53
#4 0xb7e4273e in msort_with_tmp (n=5, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
#5 msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=10) at msort.c:53
#6 0xb7e42cef in msort_with_tmp (n=10, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
#7 __GI_qsort_r (b=b@entry=0xbffff0f8, n=n@entry=10, s=s@entry=4, cmp=cmp@entry=0x804844d <comp>,
arg=arg@entry=0x0) at msort.c:297
#8 0xb7e42dcf in __GI_qsort (b=0xbffff0f8, n=10, s=4, cmp=0x804844d <comp>) at msort.c:307
#9 0x0804850d in main ()
417
24. 64- 32- 24. 64- 32-
24
64- 32-
24.1. 64-
#include <stdint.h>
uint64_t f ()
{
return 0x1234567890ABCDEF;
};
24.1.1. x86
24.1.2. ARM
|L0.12|
DCD 0x90abcdef
|L0.16|
DCD 0x12345678
418
24. 64- 32- 24. 64- 32-
24.1.3. MIPS
24.2. , ,
#include <stdint.h>
void f_add_test ()
{
#ifdef __GNUC__
printf ("%lld\n", f_add(12345678901234, 23456789012345));
#else
printf ("%I64d\n", f_add(12345678901234, 23456789012345));
#endif
};
24.2.1. x86
_f_add_test PROC
push 5461 ; 00001555H
push 1972608889 ; 75939f79H
push 2874 ; 00000b3aH
push 1942892530 ; 73ce2ff_subH
call _f_add
push edx
419
24. 64- 32- 24. 64- 32-
push eax
push OFFSET $SG1436 ; '%I64d', 0aH, 00H
call _printf
add esp, 28
ret 0
_f_add_test ENDP
_f_sub PROC
mov eax, DWORD PTR _a$[esp4]
sub eax, DWORD PTR _b$[esp4]
mov edx, DWORD PTR _a$[esp]
sbb edx, DWORD PTR _b$[esp]
ret 0
_f_sub ENDP
, 32 . , CF. -
ADC , CF = 1 .
. SUB CF, -
SBB : , .
, f_add() printf().
_f_add_test:
sub esp, 28
mov DWORD PTR [esp+8], 1972608889 ; 75939f79H
mov DWORD PTR [esp+12], 5461 ; 00001555H
mov DWORD PTR [esp], 1942892530 ; 73ce2ff_subH
mov DWORD PTR [esp+4], 2874 ; 00000b3aH
call _f_add
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp+8], edx
mov DWORD PTR [esp], OFFSET FLAT:LC0 ; "%lld\12\0"
call _printf
add esp, 28
ret
_f_sub:
mov eax, DWORD PTR [esp+4]
mov edx, DWORD PTR [esp+8]
sub eax, DWORD PTR [esp+12]
sbb edx, DWORD PTR [esp+16]
ret
GCC .
24.2.2. ARM
420
24. 64- 32- 24. 64- 32-
ENDP
f_sub PROC
SUBS r0,r0,r2
SBC r1,r1,r3
BX lr
ENDP
f_add_test PROC
PUSH {r4,lr}
LDR r2,|L0.68| ; 0x75939f79
LDR r3,|L0.72| ; 0x00001555
LDR r0,|L0.76| ; 0x73ce2ff2
LDR r1,|L0.80| ; 0x00000b3a
BL f_add
POP {r4,lr}
MOV r2,r0
MOV r3,r1
ADR r0,|L0.84| ; "%I64d\n"
B __2printf
ENDP
|L0.68|
DCD 0x75939f79
|L0.72|
DCD 0x00001555
|L0.76|
DCD 0x73ce2ff2
|L0.80|
DCD 0x00000b3a
|L0.84|
DCB "%I64d\n",0
24.2.3. MIPS
f_sub:
; $a0 a
; $a1 a
; $a2 b
; $a3 b
subu $v1, $a1, $a3 ;
subu $v0, $a0, $a2 ;
421
24. 64- 32- 24. 64- 32-
; ?
; $a0 1,
sltu $a1, $v1
jr $ra
; 1 ,
subu $v0, $a1 ; branch delay slot
; $v0
; $v1
f_add_test:
var_10 = 0x10
var_4 = 4
MIPS , .
ADC SBB x86. , ,
( SLTU), 1 0. 1 0
, .
24.3. ,
#include <stdint.h>
24.3.1. x86
422
24. 64- 32- 24. 64- 32-
24.9: MSVC 2013 /Ob1
_a$ = 8 ; size = 8
_b$ = 16 ; size = 8
_f_mul PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _b$[ebp+4]
push eax
mov ecx, DWORD PTR _b$[ebp]
push ecx
mov edx, DWORD PTR _a$[ebp+4]
push edx
mov eax, DWORD PTR _a$[ebp]
push eax
call __allmul ; long long multiplication ( long long)
pop ebp
ret 0
_f_mul ENDP
_a$ = 8 ; size = 8
_b$ = 16 ; size = 8
_f_div PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _b$[ebp+4]
push eax
mov ecx, DWORD PTR _b$[ebp]
push ecx
mov edx, DWORD PTR _a$[ebp+4]
push edx
mov eax, DWORD PTR _a$[ebp]
push eax
call __aulldiv ; unsigned long long division ( long long)
pop ebp
ret 0
_f_div ENDP
_a$ = 8 ; size = 8
_b$ = 16 ; size = 8
_f_rem PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _b$[ebp+4]
push eax
mov ecx, DWORD PTR _b$[ebp]
push ecx
mov edx, DWORD PTR _a$[ebp+4]
push edx
mov eax, DWORD PTR _a$[ebp]
push eax
call __aullrem ; unsigned long long remainder ( )
pop ebp
ret 0
_f_rem ENDP
, ,
, .
, : E (. 981).
24.10: GCC 4.8.1 -fno-inline
_f_mul:
push ebx
mov edx, DWORD PTR [esp+8]
mov eax, DWORD PTR [esp+16]
mov ebx, DWORD PTR [esp+12]
mov ecx, DWORD PTR [esp+20]
imul ebx, eax
imul ecx, edx
mul edx
423
24. 64- 32- 24. 64- 32-
add ecx, ebx
add edx, ecx
pop ebx
ret
_f_div:
sub esp, 28
mov eax, DWORD PTR [esp+40]
mov edx, DWORD PTR [esp+44]
mov DWORD PTR [esp+8], eax
mov eax, DWORD PTR [esp+32]
mov DWORD PTR [esp+12], edx
mov edx, DWORD PTR [esp+36]
mov DWORD PTR [esp], eax
mov DWORD PTR [esp+4], edx
call ___udivdi3 ; unsigned division ( )
add esp, 28
ret
_f_rem:
sub esp, 28
mov eax, DWORD PTR [esp+40]
mov edx, DWORD PTR [esp+44]
mov DWORD PTR [esp+8], eax
mov eax, DWORD PTR [esp+32]
mov DWORD PTR [esp+12], edx
mov edx, DWORD PTR [esp+36]
mov DWORD PTR [esp], eax
mov DWORD PTR [esp+4], edx
call ___umoddi3 ; unsigned modulo ( )
add esp, 28
ret
GCC , , ,
. GCC : D (. 980).
24.3.2. ARM
Keil Thumb :
||f_div|| PROC
PUSH {r4,lr}
BL __aeabi_uldivmod
POP {r4,pc}
ENDP
||f_rem|| PROC
PUSH {r4,lr}
BL __aeabi_uldivmod
MOVS r0,r2
MOVS r1,r3
POP {r4,pc}
ENDP
424
24. 64- 32- 24. 64- 32-
MLA r1,r2,r1,r4
MLA r1,r0,r3,r1
MOV r0,r12
POP {r4,pc}
ENDP
||f_div|| PROC
PUSH {r4,lr}
BL __aeabi_uldivmod
POP {r4,pc}
ENDP
||f_rem|| PROC
PUSH {r4,lr}
BL __aeabi_uldivmod
MOV r0,r2
MOV r1,r3
POP {r4,pc}
ENDP
24.3.3. MIPS
f_div:
var_10 = 0x10
var_4 = 4
f_rem:
var_10 = 0x10
var_4 = 4
425
24. 64- 32- 24. 64- 32-
sw $ra, 0x20+var_4($sp)
sw $gp, 0x20+var_10($sp)
lw $t9, (__umoddi3 & 0xFFFF)($gp)
or $at, $zero
jalr $t9
or $at, $zero
lw $ra, 0x20+var_4($sp)
or $at, $zero
jr $ra
addiu $sp, 0x20
24.4.
#include <stdint.h>
uint64_t f (uint64_t a)
{
return a>>7;
};
24.4.1. x86
: , . -
SHRD, EDX 7 , EAX, ..
. SHR: ,
.
24.4.2. ARM
426
24. 64- 32- 24. 64- 32-
24.17: Keil 6/2013 ( Thumb)
||f|| PROC
LSLS r2,r1,#25
LSRS r0,r0,#7
ORRS r0,r0,r2
LSRS r1,r1,#7
BX lr
ENDP
24.4.3. MIPS
#include <stdint.h>
int64_t f (int32_t a)
{
return a;
};
24.5.1. x86
32- 64- . -
: 0 .
: - . CDQ,
EAX, 64-, EDX:EAX . ,
CDQ EAX ( EAX) ,
32 EDX 0 1. - MOVSX.
24.5.2. ARM
427
24. 64- 32- 24. 64- 32-
Keil ARM : () 31 . ,
MSB, .
ASR r1,r0,#31, R1 0xFFFFFFFF , 0 .
R1 64- .
, MSB ( ) R0 32-
64- .
24.5.3. MIPS
428
25. SIMD 25. SIMD
25
SIMD
25.1.
2 , , ,
. , - .
.
1 http://go.yurichev.com/17329
2 Wikipedia: vectorization
429
25. SIMD 25. SIMD
: -
Cray Y-MP 1988, - Cray Y-MP EL 3 .
:
for (i = 0; i < 1024; i++)
{
C[i] = A[i]*B[i];
}
A B, C.
, 32- int, 4 128-
XMM-, B XMM- PMULLD ( DWORD
) PMULHW ( DWORD
), 4 64- .
, 1024/4 1024, 4 , , , .
25.1.1.
, , Intel C++4 .
:
int f (int sz, int *ar1, int *ar2, int *ar3)
{
for (int i=0; i<sz; i++)
ar3[i]=ar1[i]+ar2[i];
return 0;
};
Intel C++
push edi
push esi
push ebx
push esi
mov edx, [esp+10h+sz]
test edx, edx
jle loc_15B
mov eax, [esp+10h+ar3]
cmp edx, 6
jle loc_143
cmp eax, [esp+10h+ar2]
jbe short loc_36
mov esi, [esp+10h+ar2]
sub esi, eax
lea ecx, ds:0[edx*4]
neg esi
3 . : http://go.yurichev.com/17081
4 , Intel C++ : Excerpt: Effective Automatic Vectorization
430
25. SIMD 25. SIMD
cmp ecx, esi
jbe short loc_55
431
25. SIMD 25. SIMD
mov ebx, [esp+10h+ar1]
mov esi, [esp+10h+ar2]
432
25. SIMD 25. SIMD
, SSE2 :
MOVDQU (Move Unaligned Double Quadword) 16 XMM- .
PADDD (Add Packed Integers) 4 32- .
, , ,
32 . PADDD ,
16- . , 5 .
MOVDQA (Move Aligned Double Quadword) MOVDQU,
16- . , . MOVDQA MOVDQU,
.
, SSE2- 4
int ar3 16- .
, ar2 16- , :
movdqu xmm0, xmmword ptr [ebx+edi*4] ; ar1+i*4
paddd xmm0, xmmword ptr [esi+edi*4] ; ar2+i*4
movdqa xmmword ptr [eax+edi*4], xmm0 ; ar3+i*4
, , , SSE2.
GCC
push ebp
mov ebp, esp
push edi
push esi
push ebx
sub esp, 0Ch
mov ecx, [ebp+arg_0]
mov esi, [ebp+arg_4]
mov edi, [ebp+arg_8]
mov ebx, [ebp+arg_C]
test ecx, ecx
jle short loc_80484D8
cmp ecx, 6
lea eax, [ebx+10h]
ja short loc_80484E8
433
25. SIMD 25. SIMD
xor eax, eax
nop
lea esi, [esi+0]
align 8
434
25. SIMD 25. SIMD
add ebx, edx
lea esi, [esi+0]
, , Intel C++.
25.1.2.
void my_memcpy (unsigned char* dst, unsigned char* src, size_t cnt)
{
size_t i;
for (i=0; i<cnt; i++)
dst[i]=src[i];
};
GCC 4.9.1:
435
25. SIMD 25. SIMD
xor eax, eax
test rcx, rcx
je .L4
movzx eax, BYTE PTR [rsi]
cmp rcx, 1
mov BYTE PTR [rdi], al
je .L15
movzx eax, BYTE PTR [rsi+1]
cmp rcx, 2
mov BYTE PTR [rdi+1], al
je .L16
movzx eax, BYTE PTR [rsi+2]
cmp rcx, 3
mov BYTE PTR [rdi+2], al
je .L17
movzx eax, BYTE PTR [rsi+3]
cmp rcx, 4
mov BYTE PTR [rdi+3], al
je .L18
movzx eax, BYTE PTR [rsi+4]
cmp rcx, 5
mov BYTE PTR [rdi+4], al
je .L19
movzx eax, BYTE PTR [rsi+5]
cmp rcx, 6
mov BYTE PTR [rdi+5], al
je .L20
movzx eax, BYTE PTR [rsi+6]
cmp rcx, 7
mov BYTE PTR [rdi+6], al
je .L21
movzx eax, BYTE PTR [rsi+7]
cmp rcx, 8
mov BYTE PTR [rdi+7], al
je .L22
movzx eax, BYTE PTR [rsi+8]
cmp rcx, 9
mov BYTE PTR [rdi+8], al
je .L23
movzx eax, BYTE PTR [rsi+9]
cmp rcx, 10
mov BYTE PTR [rdi+9], al
je .L24
movzx eax, BYTE PTR [rsi+10]
cmp rcx, 11
mov BYTE PTR [rdi+10], al
je .L25
movzx eax, BYTE PTR [rsi+11]
cmp rcx, 12
mov BYTE PTR [rdi+11], al
je .L26
movzx eax, BYTE PTR [rsi+12]
cmp rcx, 13
mov BYTE PTR [rdi+12], al
je .L27
movzx eax, BYTE PTR [rsi+13]
cmp rcx, 15
mov BYTE PTR [rdi+13], al
jne .L28
movzx eax, BYTE PTR [rsi+14]
mov BYTE PTR [rdi+14], al
mov eax, 15
.L4:
mov r10, rdx
lea r9, [rdx1]
sub r10, rcx
lea r8, [r1016]
sub r9, rcx
shr r8, 4
add r8, 1
436
25. SIMD 25. SIMD
mov r11, r8
sal r11, 4
cmp r9, 14
jbe .L6
lea rbp, [rsi+rcx]
xor r9d, r9d
add rcx, rdi
xor ebx, ebx
.L7:
movdqa xmm0, XMMWORD PTR [rbp+0+r9]
add rbx, 1
movups XMMWORD PTR [rcx+r9], xmm0
add r9, 16
cmp rbx, r8
jb .L7
add rax, r11
cmp r10, r11
je .L1
.L6:
movzx ecx, BYTE PTR [rsi+rax]
mov BYTE PTR [rdi+rax], cl
lea rcx, [rax+1]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+1+rax]
mov BYTE PTR [rdi+1+rax], cl
lea rcx, [rax+2]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+2+rax]
mov BYTE PTR [rdi+2+rax], cl
lea rcx, [rax+3]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+3+rax]
mov BYTE PTR [rdi+3+rax], cl
lea rcx, [rax+4]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+4+rax]
mov BYTE PTR [rdi+4+rax], cl
lea rcx, [rax+5]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+5+rax]
mov BYTE PTR [rdi+5+rax], cl
lea rcx, [rax+6]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+6+rax]
mov BYTE PTR [rdi+6+rax], cl
lea rcx, [rax+7]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+7+rax]
mov BYTE PTR [rdi+7+rax], cl
lea rcx, [rax+8]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+8+rax]
mov BYTE PTR [rdi+8+rax], cl
lea rcx, [rax+9]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+9+rax]
mov BYTE PTR [rdi+9+rax], cl
lea rcx, [rax+10]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+10+rax]
437
25. SIMD 25. SIMD
mov BYTE PTR [rdi+10+rax], cl
lea rcx, [rax+11]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+11+rax]
mov BYTE PTR [rdi+11+rax], cl
lea rcx, [rax+12]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+12+rax]
mov BYTE PTR [rdi+12+rax], cl
lea rcx, [rax+13]
cmp rdx, rcx
jbe .L1
movzx ecx, BYTE PTR [rsi+13+rax]
mov BYTE PTR [rdi+13+rax], cl
lea rcx, [rax+14]
cmp rdx, rcx
jbe .L1
movzx edx, BYTE PTR [rsi+14+rax]
mov BYTE PTR [rdi+14+rax], dl
.L1:
pop rbx
pop rbp
.L41:
rep ret
.L13:
xor eax, eax
.L3:
movzx ecx, BYTE PTR [rsi+rax]
mov BYTE PTR [rdi+rax], cl
add rax, 1
cmp rax, rdx
jne .L3
rep ret
.L28:
mov eax, 14
jmp .L4
.L15:
mov eax, 1
jmp .L4
.L16:
mov eax, 2
jmp .L4
.L17:
mov eax, 3
jmp .L4
.L18:
mov eax, 4
jmp .L4
.L19:
mov eax, 5
jmp .L4
.L20:
mov eax, 6
jmp .L4
.L21:
mov eax, 7
jmp .L4
.L22:
mov eax, 8
jmp .L4
.L23:
mov eax, 9
jmp .L4
.L24:
mov eax, 10
jmp .L4
.L25:
mov eax, 11
438
25. SIMD 25. SIMD
jmp .L4
.L26:
mov eax, 12
jmp .L4
.L27:
mov eax, 13
jmp .L4
if (str_is_aligned==false)
return strlen (str);
for (;;)
{
xmm1 = _mm_load_si128((__m128i *)s);
xmm1 = _mm_cmpeq_epi8(xmm1, xmm0);
if ((mask = _mm_movemask_epi8(xmm1)) != 0)
{
unsigned long pos;
_BitScanForward(&pos, mask);