分类:
2010-03-25 23:46:16
《深入理解计算机》的第三章已经看了两遍了,一直都是在看书里的程序,一些内容都是第一次接触,也一直没有在真正的Linux上用过,今天写了下发 现和书里的还是有些出入,下面是我自己的理解。
gdb除了反汇编外,还可以用于代码的调试。下面就简单记录下容易忘记的部分。
1.gcc -g -o code code.c 这里不要忘记-g
2.watchpoint的概念
VC用惯了就是不好,在vc里ms没有这个概念,至少我没遇到过。在gdb中有一个watch命令,格式是watch + addr, 当内存中这个地址被写入新内容时程序就会中断。
3.查看内存内容的方法
X/4b &temp
这个意思就是输出7个byte从temp所在地址开始的内存内容。
比如我的temp = 0xfeff,那么会输出0xff 0xfe 0x00 0x00(小端地址法)
下面是自己花了点时间在Linux下写了一个简单的程序,并分析了下反汇编的代码,以及内存情况。
第一部分是c语言代码,编译时用gcc -o code code.c,没用-O2优化
第二部分是用gdb code的反汇编代码,';'后面是我自己的注释,关于前4句的原理可以看最下面的文章,对理解比较重要。
有疑问的部分:
0x080483d8
0x080483ec
在这里leave等价于:
mov %esp,%ebp;
pop %ebp
第三部分是内存变化的简单示意图:
-----------------------------------------------------------------------------------------------------------------------
下面来自于网上
C 代码:
int main(){
}
push %ebp
mov %esp,%ebp
sub $0x8,%esp//这句可以勉强理解,可能是为以后定义变量欲留位置,不知对否?
and $0xfffffff0,%esp//这里就不好理解了,为什么要把后面的4位全都置0???
mov $0x0, %eax
sub %eax,%esp
leave
ret
首先我觉得有必要把LEAVE替换一下,他等价于mov esp,ebp;pop ebp这两条指令.因此有如下的解释:
因此在执行了1之后的堆栈图是: ---->
这个ARG其实就是int main(int argc, char argv[]),其实这里还可以跟一个env来着
ARG[N]
..........
ARG[0]
EIP
EBP //ARG表示涵数的参数,对于MAIN涵数,POSIX定义了两个,历史上有三个的.
因此3语句的作用正好把ESP指向了为ARG[0]保留的地址,也就是跳过为EBP和EIP保留的位置
那么4语句就是为ARG[0]ARG[1]保留位置了
由于MAIN被POSIX规定了两个参数,因此不论有没有都要保留两个位置,又因为没有ARG[2]和MAIN的局部变量,所以把EAX置0,这样一举两
得,EAX又可以作为返回值,(通常涵数返回值是INT的,都用EAX表示).
其实大家可能还有不理解,那就是既然涵数的参数都已经压栈了,直接用不就行了?为什么还要拷贝过来呢?
这是C语言的要求,为了局部化,从逻辑上,EBP(含)以上都是属于主调涵数的,所以拷过来当然是必要的.否则C语言如何实现传值而不改变主调涵数的值
呢?
整个注释如下:
1:push %ebp
2:mov %esp,%ebp
3:sub $0x8,%esp //为EBP,EIP保留位置
4:and $0xfffffff0,%esp //为ARG[0],ARG[1]保留位置
5:mov $0x0, %eax //一举两用,既作返回值,有表示不需要保留位置
6:sub %eax,%esp //保留0个位置
mov %epb ,%esp //恢复ESP到PUSH %EBP指令时的位置
pop %ebp //恢复EBP的值
ret
chinaunix网友2010-03-25 23:56:29
汇编指令解释 http://wenda.sogou.com/question/56224570.html?fr=rqm 1.Rn 表示R0~R7中的一个 2.#data 表示8位的数值 00H~FFH 3.direct 表示8位的地址 00H~FFH 4.@Ri 表示寄存器间接寻址 只能是R0或者R1 5.@DPTR 表示数据指针间接寻址 6.bit 表示位地址 7.$ 表示当前地址 寄存器寻址 MOV A,R1 将R1中的数值赋予A 直接寻址 MOV A,3AH 将地址3AH中的数值赋予A 立即寻址 MOV A,#3AH 将3AH数值赋予A 寄存器间址 MOV A,@R0 将 R0中地址的数值赋予A 变址寻址 MOVC A,@A+DPTR 以A中的数值为地址偏移量进行查表 相对寻址 AJMP MATN 跳转到行号为MATNC处 位寻址 MOV C,7FH 将位地址7FH的数值赋予C MOV A,#3AH 数据传输、赋值命令 PUSH direct 将direct为地址的数值压入堆栈中 POP direct 将direct为地址的数值弹出堆栈
chinaunix网友2010-03-25 23:50:23
MOV指令 http://www.diybl.com/course/3_program/hb/hbjs/20071226/93647.html MOV DEST,SRC 操作:DEST=SRC 格式: MOV REG,IDATA 立即数赋值给寄存器 MOV MEM,IDATA 立即数赋值给内存变量 MOV REG,REG 寄存器赋值给寄存器 MOV REG,MEM 内存变量赋值给寄存器 MOV MEM,REG 寄存器赋值给内存变量 —————————————————————— MOV指令不影响任何标志位 MOV的源操作数与目标操作数类型必须一致 MOV指令的操作数不能全为内存变量 MOV指令的操作数不能全为段寄存器 段寄存器不可以直接赋值,可以通过内存变量或除段寄存器之外的其它寄存器给段寄存器赋值 CS为代码段寄存器,它是只允许读,不允许写的。(可以用跳转指令改变CS)