汇编中寄存器与指针的用法及二进制炸弹调试cmp指令问题
关于汇编寄存器、指针使用与二进制炸弹cmp指令的问题解答
先解决你遇到的二进制炸弹困惑
你卡壳的这条指令cmp (%esi),%eax je 80486d1 <main+0xaa>,核心误区在于你误解了操作数的含义:
%esi在这里是一个指针寄存器,括号()表示“解引用”——也就是取%esi中存储的地址所指向的内存单元里的值。- 所以这条指令的实际逻辑是:比较
%eax的值 和%esi指向的内存中的值,而不是比较%eax和%esi本身的地址值!
你说把%eax设成和%esi相同的值却没跳转,结合你给出的%eax值0x804a048,应该是你把%eax赋值成了%esi的地址,而不是%esi指向的内存内容。
用GDB验证并修正的步骤:
- 在cmp指令执行前,用GDB命令查看
%esi指向的内存值:
这个命令会以双字(32位整数)格式显示x/dw $esi%esi地址处的内存数据。 - 将
%eax设置为这个内存值,而不是%esi的地址:set $eax = *(int*)($esi) - 继续执行,此时
cmp会判断两者相等,触发je跳转,破解这一关。
汇编中寄存器与指针的基础使用
寄存器的核心作用
寄存器是CPU内置的高速存储单元,用来临时存储数据、内存地址、运算中间结果等。在x86架构中:
%eax、%ebx这类是通用寄存器,常用于存储数据或作为运算载体;%esi、%edi常被用作指针寄存器,专门用来存储内存地址,方便访问内存数据。
指针的汇编表示
在汇编里,指针就是存储内存地址的寄存器(或内存单元),解引用操作通过括号()实现:
(%esi):取%esi中地址指向的内存单元的值(32位环境下默认是双字);0x4(%esi):取%esi地址偏移4字节处的内存值(常用于访问结构体成员或数组元素);%eax:直接表示寄存器中存储的值,不是指针操作。
常见的指针相关指令示例
- 把
%esi指向的内存值加载到%eax:mov (%esi),%eax; - 把
%eax的值存储到%esi指向的内存:mov %eax,(%esi); - 比较
%eax和%esi指向的内存值:就是你遇到的cmp (%esi),%eax。
内容的提问来源于stack exchange,提问作者A. R.
相关产品推荐
相关产品推荐

