ã¢ã»ã³ããªèšèªãšã¯
ðæ©æ¢°èªã人éã«ãããããã圢ã§èšè¿°ããã代衚çãªäœæ°Žæºèšèªã§ãã.
äžè¬çã«ã¯æé©åã³ã³ãã€ã©ã人æã§æžãããã¢ã»ã³ããªèšèªã®ã³ãŒããšåçã®æ§èœãçºæ®ãããšèšãããŠãã.
ã¡ã¢ãª
Memory Layout
2^n-1
|---------------------|
| Stacks | ããŒã«ã«å€æ°, ããã·ãŒãžã£ã®å
容
| |
| Dynamic Data (Heap) | new ã malloc ã§ç²åŸã§ããé å
| Static Data | ã°ããŒãã«å€æ°ãªã©.
| Literals | æåå
| Instructions | ããã°ã©ã . é¢æ°
|---------------------|
0
ISA
åœä»€ã»ããã¢ãŒããã¯ãã£. (Instruction Set Architecture)
ã³ã³ãã¥ãŒã¿ã®ããŒããŠã§ã¢ã«å¯ŸããŠåœä»€ãäŒããããã®èšèã®èªåœ.
x86, x64 (x86-64) ISA
ã€ã³ãã«ã AMD ã® ISA. 32bit ã x86, 64bit ã x64.
x86, x86-64 ISA ã®ææ³
ã¬ãžã¹ã¿
load / store
- Load data from memory into %reg = Mem[address]
- Store register data into memory Mem[address] = %reg
ã¡ã¢ãªããã¡ã¢ãªãžã®ããŒã¿ç§»åã¯äžåã®æäœã§ã¯ã§ããªã. Cannot do memory-Â-memory transfer with a single instruction.
ã¬ãžã¹ã¿ã®çš®é¡
-
eax, ecx, edx, ebx, esp, ebp, esi, edi ⊠æ±çšã¬ãžã¹ã¿ (32 ããã)
-
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8~15 ⊠æ±çšã¬ãžã¹ã¿ (64 ããã)
-
eflags ⊠ãã©ã°ã¬ãžã¹ã¿ (32 ããã)
-
rflags ⊠ãã©ã°ã¬ãžã¹ã¿ (64 ããã)
-
eip ⊠ããã°ã©ã ã«ãŠã³ã¿ (32 ããã)
-
rip ⊠ããã°ã©ã ã«ãŠã³ã¿ (64 ããã)
-
st (0)~(7) ⊠FPU ã¬ãžã¹ã¿
-
FPU ã¹ããŒã¿ã¹ã¬ãžã¹ã¿ ⊠FPU ã¹ããŒã¿ã¹ã¬ãžã¹ã¿
-
FPU ã³ã³ãããŒã«ã¬ãžã¹ã¿ ⊠FPU ã³ã³ãããŒã«ã¬ãžã¹ã¿
-
xmm0~7 ⊠XMM ã¬ãžã¹ã¿
-
mxcsr ⊠MXCSR ã³ã³ãããŒã«&ã¹ããŒã¿ã¹ã¬ãžã¹ã¿
åèãªã³ã¯.
-
x86 registers
caller-Save %eax caller-Save %edx caller-Save %ecx callee-Save %ebx callee-Save %esi callee-Save %edi Special %esp Special %ebp
-
x64 registers
rax return value rbx Caller Saved rcx Argument#4 rdx Argument#3 rsi Argument#2 rdi Argument#1 rsp Stack Pointer rbp Callee saved r8 Argument#5 r9 Argument#6 r10 Caller Saved r11 Caller Saved r12 Callee Saved r13 Callee Saved r14 Callee Saved r15 Callee Saved
æ±çšã¬ãžã¹ã¿
-
%eax,%edx, %ecx
Caller saves prior to call if values are used later. åŒã³åºãå ãåŒæ°ãæž¡ãããã«å©çš.
-
%eax
ãµãã«ãŒãã³ããã®æ»ãå€ãåããšãããã«å©çšããããšãããã.
-
%ebx, %esi, %edi
Callee saves if wants to use them.
ããŒã¹ã¬ãžã¹ã¿ %rsb, %esp
ã¹ã¿ãã¯ã¬ãžã¹ã¿ %rsp, &esp
ã¹ã¿ãã¯ãã€ã³ã¿ã¯ãµãã«ãŒãã³ã³ãŒã«ã®æ»ãã¢ãã¬ã¹ãã¡ã¢ãªã«èªåçã«æ ŒçŽããã, PUSH, POP åœä»€ã§ã¬ãžã¹ã¿ãäžæçã«éé¿, 埩垰ããå Žåã«äœ¿ãããŸã.
ããã°ã©ã ã«ãŠã³ã¿ %rip, %eip
次ã«å®è¡ããåœä»€ã®ã¢ãã¬ã¹
åœä»€
mov
mov åœä»€ã¯ src ãªãã©ã³ãã dest ãªãã©ã³ãã«ã³ããŒããŸã.
mov src, dest
push, pop
ã¹ã¿ãã¯ãæäœããããã®åœä»€. ã¹ã¿ãã¯ãšã¯, ebp ãš esp ã§ã¯ããŸããã¡ã¢ãªã®ããš.
|---| %ebp
| |
| |
| |
|---| %esp
- push ã¹ã¿ãã¯ã«å€ãå
¥ãã
- Fetch value from Src
- Decrement%esp by 4
- Store value at address given by %esp
- pop ã¹ã¿ãã¯ããå€ãåãåºã
- Load value from address %esp
- Write value to Dest
- Increment %esp by 4
- leave 以äžã®äºã€ã® instruction ãšã®ç³è¡£æ§æ
- mov %ebp, %esp
- pop %ebp
call, ret
é¢æ°ã«é£ã¶.
400e79: e8 bf 03 00 00 callq 40123d <strings_not_equal>
ret ã§ãµãã«ãŒãã³ãæãã
add, sub
- å æžç®
- add eax, ecx => eax = eax + ec
lea
Address Computa?on Instruction . ã¢ãã¬ã¹èšç®åœä»€. lea åœä»€ã¯, src ãªãã©ã³ãã®ã¢ãã¬ã¹ãèšç®ã, ãã®ã¢ãã¬ã¹ã dest ãªãã©ã³ãã«ããŒãããŸã.
lea src, dest
jmp
- jmp ç¡æ¡ä»¶ãžã£ã³ã
- jc, jnc CF ãç«ã£ãŠãããã©ãã
- jz, jnz ZF ãç«ã£ãŠãããã©ãã
- js, jns SF ãç«ã£ãŠãããã©ãã
- jo, jno OF ãç«ã£ãŠãããã©ãã
test
- è«çç©
- test eax, eax
- eax=0 ãªã ZF=1 ãšãªãã®ã§ , jz åœä»€ãªã©ã§åå²
cmp
- æ¯èŒ
- cmp eax, 0
- eax=0 ãªã ZF=1 ãšãªãã®ã§ , jz åœä»€ãªã©ã§åå²
xor
- æä»çè«çå
- xor eax, eax
- åãå€å士ãªã 0 ã«ãªãã®ã§, test ã cmp ã®æºåã«å€çšããã.
x86-64 Calling Conventions (åŒåºèŠçŽ)
ããã°ã©ã ã§é¢æ°ãåŒã³åºãéã«, ã¬ãžã¹ã¿ãã¹ã¿ãã¯ã䜿ãã©ã®ããã«åŒæ°ãæž¡ãã, æ»ãå€ãã©ã®ããã«åãåããã¯åŒåºèŠçŽ (calling convention) ã§æ±ºããããŠãã
the x86-64 ISA passes the first six arguments to a function in registers. Registers are used in the following order:
rdi, rsi, rdx, rcx, r8, r9.
The return value for functions is passed in rax.
ãµãã«ãŒãã³ããããŒã°
_function:
push ebp ;ããŒã¹ãã€ã³ã¿ãä¿å
mov ebp, esp ;çŸåšã®ã¹ã¿ãã¯ãã¬ãŒã ãæãããããŒã¹ãã€ã³ã¿ãå€æŽ
sub esp, x ;å±æå€æ° (C ã§ããèªåå€æ°) ã®å€§ããã®åã¹ã¿ãã¯ãã€ã³ã¿ãæžãã
ãµãã«ãŒãã³ãšãããŒã°
mov esp, ebp ;å±æå€æ°ãé€å»
pop ebp ;ããŒã¹ãã€ã³ã¿ã埩垰
ret ;ãµãã«ãŒãã³ããæ»ã
å¶åŸ¡æ§æ
if
ãã¹ãŠ, ãäºè ãæ¯ã¹ããŠãçµæã«ãã£ãŠãžã£ã³ãã.
int absdiff (int x, int y)
{
int result;
if (x > y) {
result = x-y;
} else {
result = y-x;
}
return result;
}
int goto_ad ( int x, int y)
{
int result;
if (x <= y)
goto Else ;
result = x-y;
Exit :
return result;
Else: result = y-x;
goto Exit ;
}
int x %edx
int y %eax
absdiff :
pushl %ebp
movl %esp , %ebp
; body
movl 8 (%ebp), %edx
movl 12 (%ebp), %eax
cmpl %eax , %edx ;
jle .L7
; body end
subl %eax , %edx ; y-x
movl %edx , %eax
.L8:
leave ret
.L7:
subl %edx , %eax ; x-y
jmp .L8
while
while ( sum != 0 ) {
<loop body>
}
loopTop: cmpl $0, %eax
je loopDone
<loop body code>
jmp loopTop
loopDone:
for
for 㯠while ã®ç³è¡£æ§æ.
switch
Jump Table (indirect jmp) ãå©çšãã.
[jump table ã®ã¢ãã¬ã¹ + 8 * (åŒæ°)] ã§æ±ããããã¢ãã¬ã¹ã®å€ (switch å ã®ã¢ãã¬ã¹ãæ ŒçŽãããŠãã) ãåç §ããŠ, ãã®ã¢ãã¬ã¹ã«ãžã£ã³ããã.2 åãžã£ã³ããã. ããã Indirect ãšããæå³.
- Direct: jmp .L61
- Jump target is denoted by label .L61
- Indirect: jmp *.L62 (,%edx,4)
- Start of jump table: . L62
- Must scale by factor of 4 (labels are 32-bits = 4 bytes on IA32)
- Fetch target from effective address .L62 + edx*4
Tools
gdb
ãããã«.
ã³ã³ãã€ã«æã«-g g -O0 ãªãã·ã§ã³ãã€ããå¿ èŠããã.
$ gcc -g g -O0 ãœãŒã¹ã³ãŒãå
ãªãã·ã§ã³ | æå³ |
---|---|
-g | ãã¡ã€ã«ã«ãããã°æ å ±ãä»å ãã. |
ããããªããšãããã°æã«å€æ°åãè¡çªå·ã衚瀺ãããªã | |
-O0 | æé©åãè¡ããªã. æé©åãè¡ããš, |
ã³ãŒãã®å ¥ãæ¿ããåé€ãè¡ãããŠããŸã, ãããã°ãã«ãããªã |
ã¹ãããå®è¡
-
run (r)
ããã°ã©ã ã®å®è¡.
-
step (s)
ããã°ã©ã ãã¹ãããå®è¡. ã¹ããããªãŒããŒ.
-
stepi
ã¢ã»ã³ããªã³ãŒãã®ã¹ãããå®è¡.
-
next (n)
ããã°ã©ã ãã¹ãããå®è¡. ã¹ãããã€ã³.
-
cont (c)
ããã°ã©ã ã®åé.
ãã¬ãŒã¯ãã€ã³ãæäœ
-
breakpoint (b)
ãã¬ãŒã¯ãã€ã³ããã¯ã.
(gdb) b è¡çªå· (gdb) b é¢æ°å (gdb) b ãã¡ã€ã«å:è¡çªå·
-
info b
ãã¬ãŒã¯ãã€ã³ãã®æ å ±ã衚瀺.
-
delete (d)
ãã¬ãŒã¯ãã€ã³ãã®ã¯ãªã¢.
ã¡ã¢ãªæ å ±
-
disas
ã¢ã»ã³ããªã³ãŒãã®è¡šç€º
-
info register (info reg)
ã¬ãžã¹ã¿ã®æ å ±ã衚瀺
-
x
ã¡ã¢ãªã®ç¶æ 衚瀺, x/[衚瀺ããåæ°][åºåæžåŒ][åºååäœ]
åºååäœ æå³ b 1 ãã€ã h 2 ãã€ã w 4 ãã€ã g 8 ãã€ã (gdb) x/6xw
ã¹ãããã«ãŠã³ã¿ã® 3 ã¹ãããå ãŸã§ã衚瀺
(gdb) x /3i $rip
ã«ã¬ã³ãã¹ã¿ãã¯ãã€ã³ã¿ããã®æ å ±ã衚瀺
(gdb) x /30x $rsp (gdb) x /30xg $rsp
ã¢ãã¬ã¹ã®å€ãæåã§è¡šç€º
(gdb) x /s $eax
-
info locals (i lo)
ããŒã«ã«å€æ°è¡šç€º.
ãã®ä»
-
ããã¯ãã¬ãŒã¹ (bt)
ããã¯ãã¬ãŒã¹ãšã¯, ãŠãŒã¶ã»ããã°ã©ã ãçŸåšããç®æã«ã©ã®ããã«ããŠå°éãããã瀺ãèŠçŽæ å ±
(gdb) bt #0 0x000000000040174e in read_six_numbers () #1 0x0000000000400eac in phase_2 () #2 0x0000000000400dd5 in main (argc=<optimized out>, argv=0x7fffffffdb58) at bom
Links
objdump
- t ãã¡ã€ã«ã®ã·ã³ãã«ããŒãã«ãšã³ããªã衚瀺ããŸã. nm ã«ãã£ãŠåŸãããæ å ±ãšã»ãŒåã
- T ãã¡ã€ã«ã®åçãªã·ã³ãã«ããŒãã«ãšã³ããªã衚瀺ããŸã. ãnm -Dããšã»ãŒåã
- S (å¯èœã§ããã°) ãœãŒã¹ã³ãŒããéã¢ã»ã³ãã«çµæãšæ··åšãããŠè¡šç€ºããŸã
- d Use this to disassemble all of the code.
nm
ãªããžã§ã¯ããã¡ã€ã«ã®ã·ã³ãã«ããªã¹ããã.
Reference
- Intel ® 64 and IA-32 Architectures Software Developerâs Manual V2
- Support & Drivers
- GNU ã¢ã»ã³ãã©å ¥é (GAS)