这些车道有什么作用? 这个-0x20是怎么来的?它的目的是什么?
0x08048bab <+7>: lea -0x20(%ebp),%eax
0x08048bae <+10>: mov %eax,0x4(%esp)
这些代码来自
Dump of assembler code for function phase_2:
0x08048ba4 <+0>: push %ebp
0x08048ba5 <+1>: mov %esp,%ebp
0x08048ba7 <+3>: push %ebx
0x08048ba8 <+4>: sub $0x34,%esp
0x08048bab <+7>: lea -0x20(%ebp),%eax
0x08048bae <+10>: mov %eax,0x4(%esp)
0x08048bb2 <+14>: mov 0x8(%ebp),%eax
0x08048bb5 <+17>: mov %eax,(%esp)
0x08048bb8 <+20>: call 0x804928d <read_six_numbers>
0x08048bbd <+25>: cmpl $0x0,-0x20(%ebp)
0x08048bc1 <+29>: jns 0x8048be3 <phase_2+63>
0x08048bc3 <+31>: call 0x804924b <explode_bomb>
0x08048bc8 <+36>: jmp 0x8048be3 <phase_2+63>
0x08048bca <+38>: mov %ebx,%eax
0x08048bcc <+40>: add -0x24(%ebp,%ebx,4),%eax
0x08048bd0 <+44>: cmp %eax,-0x20(%ebp,%ebx,4)
0x08048bd4 <+48>: je 0x8048bdb <phase_2+55>
0x08048bd6 <+50>: call 0x804924b <explode_bomb>
0x08048bdb <+55>: inc %ebx
0x08048bdc <+56>: cmp $0x6,%ebx
0x08048bdf <+59>: jne 0x8048bca <phase_2+38>
0x08048be1 <+61>: jmp 0x8048bea <phase_2+70>
2
我觉得
mov 0xc(%ebp),%eax
正在获得投入。
我试过x / s $ ebp + oxc,它打印出这个字符串\ 350 \ 366 \ 377 \ 277 \ b \ 367 \ 377 \ 277&gt; \ 223 \ 004 \ b {\ 246 \ 004 \ b。 那是什么?我真的很难理解这是做什么的?我试图在每个内存地址中打印出值,但它没有帮助。
当我尝试在cmp $ 0x5,%eax之前打印出x / d $ eax时,它显示无法访问地址0x0处的内存。
Dump of assembler code for function read_six_numbers:
0x0804928d <+0>: push %ebp
0x0804928e <+1>: mov %esp,%ebp
0x08049290 <+3>: sub $0x28,%esp
0x08049293 <+6>: mov 0xc(%ebp),%eax
0x08049296 <+9>: lea 0x14(%eax),%edx
0x08049299 <+12>: mov %edx,0x1c(%esp)
0x0804929d <+16>: lea 0x10(%eax),%edx
0x080492a0 <+19>: mov %edx,0x18(%esp)
0x080492a4 <+23>: lea 0xc(%eax),%edx
0x080492a7 <+26>: mov %edx,0x14(%esp)
0x080492ab <+30>: lea 0x8(%eax),%edx
0x080492ae <+33>: mov %edx,0x10(%esp)
0x080492b2 <+37>: lea 0x4(%eax),%edx
0x080492b5 <+40>: mov %edx,0xc(%esp)
0x080492b9 <+44>: mov %eax,0x8(%esp)
0x080492bd <+48>: movl $0x804a64b,0x4(%esp)
0x080492c5 <+56>: mov 0x8(%ebp),%eax
0x080492c8 <+59>: mov %eax,(%esp)
0x080492cb <+62>: call 0x8048860 <__isoc99_sscanf@plt>
0x080492d0 <+67>: cmp $0x5,%eax
0x080492d3 <+70>: jg 0x80492da <read_six_numbers+77>
0x080492d5 <+72>: call 0x804924b <explode_bomb>
答案 0 :(得分:1)
正如迈克尔所说,sub $0x34,%esp
为局部变量创造了空间。由于mov %esp,%ebp
之前已将%esp
复制到%ebp
,因此此分配的空间也可以相对于%ebp
%ebp-0x34
到%ebp
的{{1}}来解决。 %ebp-0x20
是局部变量的地址,在这种情况下,它是大小为6的整数数组的基址(即int numbers[6];
)。此地址被加载到%eax
并随后写入到堆栈:
0x08048bab <+7>: lea -0x20(%ebp),%eax
0x08048bae <+10>: mov %eax,0x4(%esp)
适用的调用约定指定参数应在堆栈上传递。因此,这是将地址作为第二个参数传递给以下函数调用。第一个是%esp
:
0x08048bb2 <+14>: mov 0x8(%ebp),%eax
0x08048bb5 <+17>: mov %eax,(%esp)
0x08048bb8 <+20>: call 0x804928d <read_six_numbers>
请注意,当前函数的传入参数也在堆栈上,并且可以使用来自%ebp
的正偏移来解决,从8开始。因此,上面的代码将第一个传入的参数作为第一个参数传递给read_six_numbers
。总而言之,到目前为止,代码可能看起来像这样:
void phase_2(char* text)
{
int numbers[6];
read_six_numbers(text, numbers);
...
}
查看read_six_numbers
我们可以看到它获取传入的参数并为sscanf
创建一堆传出参数:
void read_six_numbers(char* text, int* numbers)
{
if (sscanf(text, "%d %d %d %d %d %d", numbers, numbers + 1,
numbers + 2, numbers + 3, numbers + 4, numbers + 5) != 6)
explode_bomb();
}
我相信你可以在汇编代码中看到这是如何完成的。
答案 1 :(得分:0)
EBP指向堆栈框架的“底部”。因此,当您需要将内容放入堆栈时,可以通过从EBP中减去来解决它。
因此,在您的示例中,它采用“EBP - 0x20”的地址并将结果存储在EAX中。