一.说明
本篇博客是基于考研之计算机组成原理中的程序机器级代码表示进行学习的,并不是从汇编语言这一门单独的课程来学习的,涉及的汇编语言知识多是帮助你学习考研之计算机组成原理中对应的考点。
二.相关寄存器
1.相关寄存器
X86处理器中有8个32位的通用寄存器,各寄存器及说明:
名称 | 说明 | 作用 |
---|---|---|
EAX | 累加器 | 什么数据都可以存 |
EBX | 基地址寄存器 | 什么数据都可以存 |
ECX | 计数寄存器 | 什么数据都可以存 |
EDX | 数据寄存器 | 什么数据都可以存 |
ESI | 变址寄存器 | 用于线性表、字符串的处理 |
EDI | 变址寄存器 | 用于线性表、字符串的处理 |
EBP | 堆栈基指针 | 用于实现函数调用 |
ESP | 堆栈顶指针 | 用于实现函数调用 |
注意:上面四个寄存器的使用非常灵活,可以只使用它的16位,甚至只使用它的8位,而后面四个寄存器则比较呆,只能单独一起使用32位。
单独使用前4个寄存器,名称如下:
2.读取长度
如何指明内存地址的读写长度:
dword ptr //双字,32bit
word ptr //单字,16bit
byte ptr //字节,8bit
三.常用指令
1.常见算术运算指令
功能 | 汇编指令格式 | 注释 |
---|---|---|
加 | add d,s | 计算d+s,结果存入d |
减 | sub d,s | 计算d-s,结果存入d |
乘 | mul d,s | 无符号数d*s,乘积存入d |
除 | div d,s | 无符号数除法:edx:eax/s,商存入eax,余数存入edx |
取负数 | neg d,s | 将d取负数,结果存入d |
自增++ | inc d,s | 将d++,结果存入d |
自减– | dec d,s | 将d–,结果存入d |
乘 | imul d,s | 有符号数d*s,乘积存入d |
除 | idiv d,s | 有符号数除法:edx:eax/s,商存入eax,余数存入edx |
注意1:这里面需要注意的是除法运算edx:eax是什么意思,在除法运算时,首先被除数要进行位扩展,把32位扩展为64位,再用64位的被除数除32位的除数,商存入eax,余数存入edx。这里面使用的隐含寻址的数据寻址方式,2个寄存器(32位)连起来使用存储64位的被除数,所以用:号连接。
2.常见逻辑运算指令
功能 | 汇编指令格式 | 注释 |
---|---|---|
与 | add d,s | 将d、s逐位相与,结果放回d |
或 | or d,s | 将d、s逐位相或,结果放回d |
非 | not d | 将d逐位取反,结果放回d |
异或 | xor d,s | 将d、s逐位异或,结果放回d |
左移 | shl d,s | 将d逻辑左移s位,结果放回d(通常s是常量,即立即数) |
右移 | shr d,s | 将d逻辑右移s位,结果放回d(通常s是常量,即立即数) |
补充:这里常见的逻辑运算和算术运算,如果你不了解,可以查看逻辑与算术运算
3.补充指令
- 功能:数据传送
- 指令格式:mov d,s
- 注释:将第二个操作数复制到第一个操作数,但不能用于直接从内存复制到内存
四.汇编格式
使用不同的编程工具开发程序时,用到的汇编程序也不同,一般有两种不同的汇编格式:AT&T格式和Intel格式。
我们之前学的X86汇编语言都是Intel格式。
两种格式需要注意的点都在这里了。
五.选择语句的机器级表示
1.无条件转移指令-jmp
jmp <地址>
PC无条件转移至<地址>jmp 128
<地址>可以用常数给出jmp [999]
<地址>可以来自于主存jmp eax
<地址>可以来自于寄存器jmp NEXT
<地址>可以用“标号”锚定
2.有条件转移指令
需要注意的是,因为是有条件注意,所以它经常和cmp
比较指令一起组合使用
例如:
cmp eax,ebx #比较寄存器eax和ebx里的值
jg NEXT #若eax > ebx,则跳转到NEXT:
3.C语言程序编译成汇编程序
示例如下:
六.循环语句机器级表示
循环语句我们非常熟悉了,也知道他们之间可以互相转换。
例如:
int result = 0;
for(int i=0;i<=100<i++){
result +=i;
}
可以转化为while循环
int i=1;
int result = 0;
while(i<=100){
result +=i;
i++;
}
那么转化的汇编语言程序是什么呢?
mov eax 0 #用eax保存result, 初值为0
mov edx, 1 #用edx保存i, 初始值为1
cmp edx,100 #比较i和100
jg L2 #若i>100,转跳到L2执行
L1 : #循环主体
add eax,edx #实现result +=i
inc edx #inc自增指令,实现i++
cmp edx,100 #i和100
jleL1 #若i<=100,转跳到L1执行
L2 : #跳出循环主体
这里补充介绍一条命令:
loop NEXT
<===>
dec ecx
cmp ecx,0
jne NEXT
理论上能用loop指令实现的功能,也一定能用条件转移实现。
补充:本篇博客仅仅针对于考研之计算机组成原理指令系统这一章节,仅作了解即可。