iOS 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