240 likes | 409 Views
Recitation 2: Assembly & gdb. Andrew Faulring 15213 Section A 16 September 2002. Andrew Faulring. faulring@cs.cmu.edu Office hours: NSH 2504 (lab) / 2507 (conference room) Normally Thursday 5 – 6 THIS WEEK: Wednesday 5 – 6. Today’s Plan. Preparing for Lab2
E N D
Recitation 2:Assembly & gdb Andrew Faulring 15213 Section A 16 September 2002
Andrew Faulring • faulring@cs.cmu.edu • Office hours: • NSH 2504 (lab) / 2507 (conference room) • Normally Thursday 5–6 • THIS WEEK: Wednesday 5–6
Today’s Plan • Preparing for Lab2 • due Thursday, 26 Sep @ 11:59PM • Assembly programming • C to ASM • Using gdb • ASM to C • Reverse engineering (like in Lab2)
Machine Model CPU Memory Addresses Registers E I P Object Code Program Data Data Condition Codes Instructions Stack
Special Registers • %eax Return Value • %eip Instruction Pointer • %ebp Base (Stack Frame) Pointer • %esp Stack Pointer
Simple Addressing Modes • $10 10 • (R) Mem[R] • $10(R) Mem[R + 10] • $0x10(R) Mem[R + 16]
Indexed Addressing Modes Generic Form • D(Rb, Ri, S) Mem[Reg[Rb]+S*Reg[Ri]+D] Examples • (Rb,Ri) Mem[Reg[Rb]+Reg[Ri]] • D(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]+D] • (Rb,Ri,S) Mem[Reg[Rb]+S*Reg[Ri]]
Example 1: Arithmetic int func1(int a, int b) { int x, y; x = a + b; y = 2*x - b; return x*y; }
func1 assembly func1: push %ebp # save frame pointer mov %esp,%ebp # frame ptr = stack ptr mov 0xc(%ebp),%eax # %eax = b mov 0x8(%ebp),%ecx # %ecx = a add %eax,%ecx # %ecx = x = a + b lea (%ecx,%ecx,1),%edx # %edx = 2 * x sub %eax,%edx # %edx = y = 2 * x - b mov %ecx,%eax # %eax = x imul %edx,%eax # %eax = x * y mov %ebp,%esp # restore stack pointer pop %ebp # restore frame pointer ret
gdb • GNU debugger • Your friend for Lab2 • Usage • gdb <executable name>
gdb commands • run: starts the program, can include command line arguments • disas: disassembles code into asm • print: used to print values of variables & memory • x: examine memory contents • step, next: step through code • break: set breakpoints in the code
Example 2: Control int func2(int a, int b) { if(a>b) return a; else return b; }
ASM for func2 func2: push %ebp # save frame pointer mov %esp,%ebp # frame ptr = stack ptr mov 0x8(%ebp),%edx # %edx = a mov 0xc(%ebp),%eax # %eax = b cmp %eax,%edx # a > b jle .L1 # a <= b mov %edx,%eax # return a .L1: # otherwise %eax = b mov %ebp,%esp # restore stack pointer pop %ebp # restore frame pointer ret
Example 3: int func3(int a, int b) { int r = 0xDEADBEEF; switch(a) { case 0: r = a; break; case 1: r = b; break; case 2: r = a+b; break; case 3: r = a-b; break; case 4: r = a*b; break; } return r; }
ASM for func3 # $edx = a, $ecx = b, $eax = 0xdeadbeef 0x8048453 <func3+3>: mov 0x8(%ebp),%edx 0x8048456 <func3+6>: mov 0xc(%ebp),%ecx 0x8048459 <func3+9>: mov $0xdeadbeef,%eax # go to default case, if a > 4 0x804845e <func3+14>: cmp $0x4,%edx 0x8048461 <func3+17>: ja 0x804848b <func3+59> # execute the jump … 0x8048463 <func3+19>: jmp *0x8048578(,%edx,4) 0x804846a <func3+26>: lea 0x0(%esi),%esi
ASM for func3 case 0: return a 0x8048470 <func3+32>: mov %edx,%eax 0x8048472 <func3+34>: jmp 0x804848b <func3+59> case 1: return b 0x8048474 <func3+36>: mov %ecx,%eax 0x8048476 <func3+38>: jmp 0x804848b <func3+59> 0x8048478 <func3+40>: lea (%ecx,%edx,1),%eax case 2: return a+b 0x8048478 <func3+40>: lea (%ecx,%edx,1),%eax 0x804847b <func3+43>: jmp 0x804848b <func3+59> 0x804847d <func3+45>: lea 0x0(%esi),%esi
ASM for func3 case 3: a-b 0x8048480 <func3+48>: mov %edx,%eax 0x8048482 <func3+50>: sub %ecx,%eax 0x8048484 <func3+52>: jmp 0x804848b <func3+59> case 4: a*b 0x8048486 <func3+54>: mov %edx,%eax 0x8048488 <func3+56>: imul %ecx,%eax
Addresses of the cases • case 0: 0x8048470 • case 1: 0x8048474 • case 2: 0x8048478 • case 3: 0x8048480 • case 4: 0x8048486
The Jump Table 0x8048463 <func3+19>: jmp *0x8048578(,%edx,4) (gdb) x/5xw 0x8048578 0x8048578 <_IO_stdin_used+4>: 0x08048470 0x08048474 0x08048478 0x08048480 0x8048588 <_IO_stdin_used+20>: 0x08048486 %edx = a Jump to instruction with address MEM[0x8048578 + a*4]
Example 4: asm => c Dump of assembler code for function func4: 0x80483c0 <func4>: push %ebp 0x80483c1 <func4+1>: mov %esp,%ebp 0x80483c3 <func4+3>: mov 0x8(%ebp),%ecx 0x80483c6 <func4+6>: xor %eax,%eax 0x80483c8 <func4+8>: xor %edx,%edx 0x80483ca <func4+10>: cmp %ecx,%eax 0x80483cc <func4+12>: jge 0x80483d7 <func4+23> 0x80483ce <func4+14>: mov %esi,%esi 0x80483d0 <func4+16>: add %edx,%eax 0x80483d2 <func4+18>: inc %edx 0x80483d3 <func4+19>: cmp %ecx,%edx 0x80483d5 <func4+21>: jl 0x80483d0 <func4+16> 0x80483d7 <func4+23>: mov %ebp,%esp 0x80483d9 <func4+25>: pop %ebp 0x80483da <func4+26>: ret 0x80483db <func4+27>: nop End of assembler dump.
Examining func4 <func4>: pushl %ebp # save frame pointer movl %esp,%ebp # frame ptr = stack ptr movl 0x8(%ebp),%ecx # put arg1 into %ecx xorl %eax,%eax # zero %eax xorl %edx,%edx # zero %edx
Examining func4 cmpl %ecx,%eax # compare arg1 (%ecx) and %eax jge .L4 # jump to .L4 if arg1 <= %eax (0) .L6: addl %edx,%eax # %eax = %eax + %edx incl %edx # %edx = %edx + 1 cmpl %ecx,%edx # compare arg1 (%ecx) and %edx jl .L6 # jump to .L06 if %edx < arg1 .L4: movl %ebp,%esp # restore stack pointer popl %ebp # restore frame pointer ret
Name the variables %ecx: x (first argument) %eax: result %edx: i
func4 int func4(int x) // %ecx = x { int result = 0; // %eax = result int i; // %edx = i for (i = 0; i < x; i++) result += i; return result; }