阅读更多
main 启动对应机器码分析
0x2730: pushl $0 ( 将出错码入栈)
当异常发生时,如果控制单元没有自动地把一个硬件错误代码插入到栈中,相应的汇编语言片段会包含一条pushl $0指令,在栈中垫上一个空值,如果错误码已经被压入堆栈,则没有这条指令。然后,把异常处理函数的地址压进栈中;函数的名字由异常处理程序名与do_前缀组成
0x2732: movl %esp, %ebp
栈指址(低地址)%esp栈顶值赋给栈基址(高地址)%ebp栈底,设置 main函数的栈基址
0x2734: andl $-16, %esp
它等价于 andl $0xfffffff0,%esp,也就是说把%esp内的最后4位给抹掉,强制让%esp的值是16的倍数,GCC默认的堆栈是16字节对齐的,为了加快CPU的访问效率
0x2737: subl $16, %esp
%esp栈顶向下移动16个字节,给临时变量留出来
0x273a: movl 4(%ebp), %ebx
保存旧的栈基址,4(%ebp)等于 : (%ebp +4) ,%ebp + 4
是表示一个地址值,加上括号表示存储在该地址上的内容
0x273d: movl %ebx, (%esp)
复制对齐的指针 ,把%ebx的值写到栈顶,但不会使栈指针值发生变化
0x2740: leal 8(%ebp), %ecx
局部变量的地址直到程序运行才能被识别,必须用leal指令寻址。但leal的效率相对movl xxx要低得多 ,传送%ebp+8的地址写到%ecx寄存器
0x2743: movl %ecx, 4(%esp)
把%ecx的值写到%esp+4
0x2747: addl $1, %ebx
%ebx+1
0x274a: shll $2, %ebx
%ebx 左移2位
0x274d: addl %ecx, %ebx
%ebx+ %ecx
0x274f: movl %ebx, 8(%esp)
把%ebx值写到%esp+8
0x2753: movl (%ebx), %eax
把%ebx值写到%eax寄存器
0x2755: addl $4, %ebx
%ebx+4
0x2758: testl %eax, %eax
testl的执行会影响状态寄存器。%eax & %eax
如果al不为0,则testb %eax , %eax,标志位NZ为1
0x275a: jne 0x2753 ; start + 35
jne不等于时转移
0x275c: movl %ebx, 12(%esp)
把%ebx值写到%esp+12
0x2760: calll 0x27b0 ; main at main.m:14
calll 将当前的IP压栈后,转到标号处执行指令
调用0x27b0标示的程序
0x2765: movl %eax, (%esp)
把%eax值写到%esp
0x2768: calll 0xb2db6 ; symbol stub for: exit
调用0xb2db6标示的程序
0x276d: hlt
cpu暂停,等到有复位信号或中断信号输入再运行
0x276e: nop
空指令,就是让cpu等待一个周期,可能等待外设输入
0x276f: nop