2015-02-06 149 views
1
0x08048c62 <+0>:  sub $0x2c,%esp 
    0x08048c65 <+3>:  lea 0x1c(%esp),%eax 
    0x08048c69 <+7>:  mov %eax,0xc(%esp) 
    0x08048c6d <+11>: lea 0x18(%esp),%eax 
    0x08048c71 <+15>: mov %eax,0x8(%esp) 
    0x08048c75 <+19>: movl $0x804a73d,0x4(%esp) 
    0x08048c7d <+27>: mov 0x30(%esp),%eax 
    0x08048c81 <+31>: mov %eax,(%esp) 
    0x08048c84 <+34>: call 0x80488d0 <[email protected]> 
=> 0x08048c89 <+39>: cmp $0x1,%eax 

如何在最后一条指令中打印出$0x1处的内容? 我尝试了所有组合gdb:如何打印ASM内存地址的值

x/d 0x1 
x/d $0x1 
x/s $0x1 
... 
... 

但我要么得到 错误:在地址为0x1不能访问存储器,或值不能转换成整数(甚至当我尝试改变类型为C,S,X,A )

最终,我试图找出传递给scanf的参数,即“%d%d%C”

回答

4

$1有一个直接的价值,它只是数1。这不是一个地址。它正在检查返回值sscanf,即处理的物品数量。转换后的值当然会放在已经传递给参数sscanf的指针的内存中。

在您的示例中,格式字符串为0x804a73d,您应该可以使用x/s 0x804a73d打印该字符串。

出于效率原因,代码使用mov将物品放入堆栈而不是push。您可以在堆栈中以正确的偏移量查看参数。他们开始在(%esp)各为4个字节:

第一个参数(字符串从阅读):

0x08048c7d <+27>: mov 0x30(%esp),%eax 
    0x08048c81 <+31>: mov %eax,(%esp) 

第二个参数(格式字符串):

0x08048c75 <+19>: movl $0x804a73d,0x4(%esp) 

第三个参数(第1输出指针):

0x08048c6d <+11>: lea 0x18(%esp),%eax 
    0x08048c71 <+15>: mov %eax,0x8(%esp) 

第四个参数(第二个输出指针):

0x08048c65 <+3>:  lea 0x1c(%esp),%eax 
    0x08048c69 <+7>:  mov %eax,0xc(%esp) 
+0

那么我的问题是现在:我怎么知道什么传递给scanf作为参数,当我没有看到任何推指令? – SSOPLIF 2015-02-06 02:03:04

+0

@filposs查找'mov'到内存地址,例如'(%esp)','4(%esp)'等。这与'push'类似,但不必每次都减少'%esp' 。 – 2015-02-06 02:05:33

+0

你知道它在那里似乎没有任何问题!你介意给我解释一个有洞见的方法来确定吗?所有mov指令中,我怎么知道它的这个? (这是%d%d) – SSOPLIF 2015-02-06 02:06:44