计组-4.3指令的汇编格式
4.3.1-1 汇编语言中的 地址码
==指令格式 = 操作码 + 地址码==
==探讨的:如何在汇编语言中指明指令的数据(操作码)存放在什么地方。(关注于地址码)==
==下一节:汇编语言指令可以对数据进行哪些处理。(关注于操作码)==
前言
- 高级语言→汇编语言→机器语言

汇编角度看待指令
关于寄存器
- 三类常见寄存器
(少见的情况)
- 通用寄存器 可以把E去掉,用低16bit,甚至用某个低8bit。
- 其他寄存器固定32bit


(补充)
- 【ebx】指的是ebx所指的主存地址
- ==未指明默认32bit==
总结

4.3.1-2 汇编语言中的 操作码
==这一节:汇编语言指令可以对数据进行哪些处理。(关注于操作码)==

算术运算
- destination不可以是常量,只能是寄存器或者主存。source都可。
- i - integer带符号的整数
- div s ,s是除数,被除数提前放在edx,eax。(高位存余低位存商)(被除数需要提前扩展(位数*2),所以需要两个寄存器)

逻辑运算

其他指令

4.3.1-3 AT&T 格式 v.s. intel 格式


4.3.2 选择语句的机器级表示
- PC (program counter)也被称为 IP(instruction pointer)
无条件转移指令jmp

条件转移指令jxxx

(简单例子)


扩展:cmp指令底层原理

4.3.3 循环语句的机器级表示
用 条件转移指令 实现循环

用 loop指令 实现循环
- (ecx是专门用于循环计数器的,eax ebx edx都不行)
- 理论上只要能用loop指令实现的功能,都可以用条件转移指令实现。(只是 loop指令更简洁,且jxxx第一印象可能是分支而不是循环(但并非如此哈哈哈))

4.3.4 函数调用的机器级表示
待解决的:
函数调用过去和回来的过程 – 1
如何访问栈帧里的数据 – 2
如何传递调用参数,返回值 – 4
栈帧内可能包含哪些内容 – 4
call和ret指令
高级语言视角下的 函数调用


x86汇编语言视角下的 函数调用

如何访问栈帧
函数调用栈 在内存中的位置

==栈帧:==
- ebp寄存器 指向栈帧“底部”(extend base pointer)
- esp寄存器 指向栈帧“顶部 (extend stack pointer)
- ebp和esp之间的内容就是栈帧的范围
其他:
- 入栈 - 4,因为高地址是栈底,低地址是栈顶
- 默认4字节为单位
- 出栈不能pop+元素,原因同destination
访问栈帧数据的方式①:push,pop指令

访问栈帧数据的方式②:mov指令

如何切换栈帧
(栈指针怎么变)
函数调用时,栈指针的变化


函数返回时,栈指针的变化

(注:每一个栈帧的底部,用于保存上一层栈帧的基址)

ret的作用

函数调用时栈指针的变化(总)


如何传递参数和返回值+指针包含的内容
指针包含的内容
- (like [ebp==-==4]这类就是指局部变量)

- (此处是add函数,[ebp==+==8]这类指的是调用函数)

- (有空闲的区域是正常的)

- 调用参数发生在call(下一fuc)指令之前

实战
- 压入上一层栈帧基址

- esp-24,划出了栈帧的范围

- 局部变量的初始化

- 调用add的参数发生在add函数call之前
- (mov指令是不能两个操作数都来自主存的,所以此处需两步)
- (x的参数调用同y)

- call指令,把ip的旧值压到栈顶
- ==同时程序的执行流,转移到add函数的第一条指令==

- push指令把caller函数的栈帧基地址保存下来(0xA00F…)
- move指令让ebp指针指向当前函数的基地址(esp所指的)

- 访问add需要的两个参数x,y
- 后add,并把结果写回eax

- leave指令,切换回上层函数的栈帧

- 执行return指令,让程序的指令流回到上一层函数

- ==通常用eax返回结果==
- 用eax把 add函数的返回值 返回到sum变量【ebp-4处】

- caller函数 把sum的值返回给 上一层函数 【先返回到eax寄存器里】

总结



评论
