考虑以下示例代码:
program code
build/program-x86: file format elf32-i386
Disassembly of section my_text:
080a9dfc <subroutine_fnc>:
80a9dfc: 55 push %ebp
80a9dfd: 89 e5 mov %esp,%ebp
80a9dff: 57 push %edi
80a9e00: 56 push %esi
80a9e01: 53 push %ebx
80a9e02: 83 ec 14 sub $0x14,%esp // 20 bytes for local variables
80a9e05: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) // zero local variable at address bp-0x20
80a9e0c: 8d 7d f3 lea -0xd(%ebp),%edi // pointer in area of the local variables
80a9e0f: 8b 75 0c mov 0xc(%ebp),%esi // 2. parameter
80a9e12: 83 c6 30 add $0x30,%esi // add ascii ASCII '0' to the parameter
80a9e15: ba 01 00 00 00 mov $0x1,%edx // constatnt 1
80a9e1a: 8b 5d 08 mov 0x8(%ebp),%ebx // 1. function parameter
80a9e1d: 89 f9 mov %edi,%ecx // local buffer
80a9e1f: b8 03 00 00 00 mov $0x3,%eax // syscall read
80a9e24: cd 80 int $0x80 // read(par1, ptr to local var, 1)
80a9e26: 83 f8 01 cmp $0x1,%eax // return value is 1?
80a9e29: 74 0c je 80a9e37 <subroutine_fnc+0x3b> // yes
80a9e2b: bb 01 00 00 00 mov $0x1,%ebx
80a9e30: b8 01 00 00 00 mov $0x1,%eax
80a9e35: cd 80 int $0x80 // no exit(1)
80a9e37: 0f b6 45 f3 movzbl -0xd(%ebp),%eax // expand value to 32 bits
80a9e3b: 3c 2f cmp $0x2f,%al // is value < ASCII '0'
80a9e3d: 7e 17 jle 80a9e56 <subroutine_fnc+0x5a> // yes end of the subroutine
80a9e3f: 0f be d0 movsbl %al,%edx
80a9e42: 39 f2 cmp %esi,%edx // is value above >= par2 + '0'
80a9e44: 7d 10 jge 80a9e56 <subroutine_fnc+0x5a> // yes => end
80a9e46: 8b 45 0c mov 0xc(%ebp),%eax // read again param2
80a9e49: 0f af 45 e0 imul -0x20(%ebp),%eax // multiply ebp-0x20 by param2
80a9e4d: 8d 54 10 d0 lea -0x30(%eax,%edx,1),%edx // add result with read character - ASCII '0'
80a9e51: 89 55 e0 mov %edx,-0x20(%ebp) // store result to the local variable at ebp-0x20
80a9e54: eb bf jmp 80a9e15 <subroutine_fnc+0x19> // repeat
80a9e56: 8b 45 e0 mov -0x20(%ebp),%eax // function returns value from local variable at ebp-0x20
80a9e59: 83 c4 14 add $0x14,%esp
80a9e5c: 5b pop %ebx
80a9e5d: 5e pop %esi
80a9e5e: 5f pop %edi
80a9e5f: 5d pop %ebp
80a9e60: c3 ret
080a9e61 <toplevel_fnc>:
80a9e61: 55 push %ebp
80a9e62: 89 e5 mov %esp,%ebp
80a9e64: 57 push %edi
80a9e65: 56 push %esi
80a9e66: 53 push %ebx
80a9e67: 83 ec 20 sub $0x20,%esp // reserve stack space for local variables
80a9e6a: c6 45 f3 41 movb $0x41,-0xd(%ebp) // store ASCII 'A' at ebp-0xd
80a9e6e: c7 44 24 04 0a 00 00 movl $0xa,0x4(%esp) // store 10 to the first 32-bit slot bellow stack top
80a9e75: 00
80a9e76: c7 04 24 00 00 00 00 movl $0x0,(%esp) // store zero to the stack top
80a9e7d: e8 7a ff ff ff call 80a9dfc <subroutine_fnc> // call subroutine_fnc(0,10)
80a9e82: 89 c7 mov %eax,%edi // store result
80a9e84: ba 80 01 00 00 mov $0x180,%edx
80a9e89: b9 42 02 00 00 mov $0x242,%ecx
80a9e8e: be 00 7f 0c 08 mov $0x80c7f00,%esi // setup pointer to "data"
80a9e93: 89 f3 mov %esi,%ebx
80a9e95: b8 05 00 00 00 mov $0x5,%eax // syscall open
80a9e9a: cd 80 int $0x80 // open("data", 0x242, 0x180)
80a9e9c: 89 45 dc mov %eax,-0x24(%ebp) // store result to ebp-0x24
80a9e9f: 85 c0 test %eax,%eax // set flags according to the eax test
80a9ea1: 79 0e jns 80a9eb1 <toplevel_fnc+0x50> // sign is not set (>=0)
80a9ea3: b8 01 00 00 00 mov $0x1,%eax
80a9ea8: 89 c3 mov %eax,%ebx
80a9eaa: b8 01 00 00 00 mov $0x1,%eax // syscall exit
80a9eaf: cd 80 int $0x80 // exit(1)
80a9eb1: 89 7d e0 mov %edi,-0x20(%ebp) // store subroutine_fnc result into ebp-0x20
80a9eb4: 8d 75 f3 lea -0xd(%ebp),%esi // ebp-0xd is pointer to the 'A' character
80a9eb7: eb 22 jmp 80a9edb <toplevel_fnc+0x7a>
80a9eb9: 8b 5d dc mov -0x24(%ebp),%ebx // fill ebx by open result (fd)
80a9ebc: 89 f1 mov %esi,%ecx // pointer to 'A'
80a9ebe: ba 01 00 00 00 mov $0x1,%edx
80a9ec3: b8 04 00 00 00 mov $0x4,%eax // syscall write
80a9ec8: cd 80 int $0x80 // write(fd from open, "A", 1)
80a9eca: 85 c0 test %eax,%eax // check result
80a9ecc: 79 09 jns 80a9ed7 <toplevel_fnc+0x76>
80a9ece: 89 d3 mov %edx,%ebx // setup sign
80a9ed0: b8 01 00 00 00 mov $0x1,%eax
80a9ed5: cd 80 int $0x80 // exit(1)
80a9ed7: 83 6d e0 01 subl $0x1,-0x20(%ebp) // subtract 1 from ebp-0x20
80a9edb: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) // value 0 reached
80a9edf: 75 d8 jne 80a9eb9 <toplevel_fnc+0x58> // no => repeat
80a9ee1: 8b 5d dc mov -0x24(%ebp),%ebx // fd from open syscall
80a9ee4: b8 06 00 00 00 mov $0x6,%eax // syscall close
80a9ee9: cd 80 int $0x80 // close(fd from open)
80a9eeb: 85 c0 test %eax,%eax // test result
80a9eed: 79 0e jns 80a9efd <toplevel_fnc+0x9c>
80a9eef: b8 01 00 00 00 mov $0x1,%eax
80a9ef4: 89 c3 mov %eax,%ebx
80a9ef6: b8 01 00 00 00 mov $0x1,%eax
80a9efb: cd 80 int $0x80 // for error exit exit(1)
80a9efd: 89 f8 mov %edi,%eax // restore saved result of
// subroutine_fnc call
80a9eff: 83 c4 20 add $0x20,%esp
80a9f02: 5b pop %ebx
80a9f03: 5e pop %esi
80a9f04: 5f pop %edi
80a9f05: 5d pop %ebp
80a9f06: c3 ret
program data
build/program-x86: file format elf32-i386
Contents of section my_data:
80c7f00 64617461 00 data.
一般来说,我如何才能了解subroutine_fnc
使用了哪些参数?我对这个的一般方法感兴趣。我知道这可能并不总是 100% 可能,但至少我对学习基础知识很感兴趣。