240 likes | 428 Views
This document provides a detailed overview of Assembly programming and debugging with gdb, targeted towards students preparing for Lab2. It includes insights into converting C code to ASM, reverse engineering, and understanding the machine model, including CPU memory addresses and registers. Furthermore, it covers practical usage of gdb commands, such as running programs, disassembling code, and examining memory contents. Examples of assembly functions illustrate key concepts and instructions in assembly programming.
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; }