概述
汇编语言简介
- 编译流程
- 汇编是什么
- 实模式和保护模式
- 寄存器介绍
- 四个数据寄存器
- 两个变址寄存器
- 两个指针寄存器
- 六个段寄存器
- 一个指令指针寄存器
- 一个标志寄存器
- 堆栈模型
- 具体指令
- 通用数据传输指令
- 输入输出端口传送指令
- 目的地址传送指令
- 标志传送指令
- 算数运算指令
- 串指令
- 无条件转移指令
- 条件转移指令
- 循环控制指令
- 中断指令
- 处理器控制指令
- 伪指令
- 标志处理指令
- nasm简介
编译流程
不知道你有没有思考过,咱们平时写的c程序,是如何被编译成可执行文件的?比如我有main.c & some.c & some.h这三个文件组成一个proj,且main.c和some.c都include了some.h。
1.预处理阶段。
这一阶段主要是处理一些条件编译、源文件包含、宏替换、行控制、抛错、杂注和空指令等,知道有这回事情就行。单个文件自己玩自己。
2.编译阶段
编译生成汇编程序。当然生成的汇编语言格式可能有所不同,有的是AT&T格式的汇编,有的是intel。单个文件自己玩自己。
3.汇编阶段
将汇编代码转换成更低一级的机器码,一般是obj文件。这个东西长啥样?去Linux下用objdump查看一下section分区信息,这里不展开。单个文件自己玩自己。
4.链接阶段
将所有的obj文件链接在一起,生成最终的可执行文件。大家一起玩。
对于编译流程,大家先暂时理解个大概,不影响后续学习汇编。
汇编是什么
从上面的编译过程中我们不难发现,汇编语言也就是比机器语言(一串二进制)高级那么一点点。目前我知道的汇编语言风格有intel和AT&T的,似乎教学中前者出现频率最高,而实际项目中查看汇编时会有AT&T格式汇编出现。其实也就是一点语法上的不同而已。
实模式和保护模式
我对这俩模式了解的不深入,大概是80286为分界线,早一些的是16位的实模式;80286好像是20位的,不伦不类,也就不深究了;以后的都是保护模式,是32位的。
其实16位和32位不能说是区分实模式和保护模式的最大特点。但是这不影响后续学习。
寄存器介绍
学了汇编你会发现,这东西经常和寄存器打交道(根本就是一直在和寄存器打交道!),所以怎么都绕不开寄存器。寄存器就是CPU直接访问的东西,比内存快多了。
80286以前的CPU是16位的,寄存器也是16位的,比如ax,bx,cx,dx等等。后来发展起来以后呢,CPU变成32位了,于是大部分寄存器就新增了高16位来扩展原有的寄存器,统称为eax,ebx等等。咱们就不碰16位的东西了,直接学习32位的寄存器。下面咱们重点介绍这几个32位的寄存器。
四个数据寄存器
数据寄存器 | 描述 |
---|
EAX | 通常作为累加器,当然你想用做其他也行,就是这么个默认的说法。可以单独访问低16位,称为AX,还可以访问AX中的AH和AL,很灵活的。下面三个也是如此。 |
EBX | 基址寄存器。 |
ECX | 计数寄存器,一般用在循环次数,或者移位操作等。 |
EDX | 数据寄存器,一般存放运算数据,或者IO操作存放端口号。 |
两个变址寄存器
变址寄存器 | 描述 |
---|
ESI & EDI | 主要用于存放存储单元在段内的偏移量,在字符串操作中有特殊要求。 |
两个指针寄存器
指针寄存器 | 描述 |
---|
ESP | 用它访问栈顶数据,会随着带有堆栈操作的指令(比如PUSH、CALL、INT、RETF)产生变化 |
EBP | 用它访问栈的任意位置数据,不会随着带有堆栈操作的指令产生变化,因此在带参数的子过程中用BP来获取参数和访问设在堆栈里面的临时变量 |
六个段寄存器
段寄存器 | 描述 |
---|
CS | 代码段寄存器,为代码段的段基址 |
DS | 数据段寄存器,为数据段的段基址 |
ES | 附加段寄存器,为附加段的段基址,这个寄存器比较灵活,可做他用。 |
FS | 附加段寄存器,为附加段的段基址,这个寄存器比较灵活,可做他用。 |
GS | 附加段寄存器,为附加段的段基址 |
SS | 堆栈段寄存器,为堆栈段的段基址 |
一个指令指针寄存器
指令指针寄存器 | 描述 |
---|
EIP | 存放下次将要执行的指令在代码段的偏移地址 |
一个标志寄存器
堆栈模型
堆栈堆栈,其实说的是栈stack。这个东西大家都知道,先进后出,对吧。用来保护现场环境,传递一些参数,都是很有用的。
在内存中,stack的基址是高地址,增长方向是向低地址前进。
这东西着实简单,对用push和pop操作,后面介绍。
具体指令
这里引用@知乎 爱是等待是细水长流的一篇指令说明,侵删。
通用数据传输指令
通用数据传送指令 | 描述 |
---|
MOV | 传送字或字节. |
MOVSX | 先符号扩展,再传送. |
MOVZX | 先零扩展,再传送. |
PUSH | 把字压入堆栈. |
POP | 把字弹出堆栈. |
PUSHA | 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈. |
POPA | 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈. |
PUSHAD | 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈. |
POPAD | 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈. |
BSWAP | 交换32位寄存器里字节的顺序 |
XCHG | 交换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数) |
CMPXCHG | 比较并交换操作数.(第二个操作数必须为累加器AL/AX/EAX) |
XADD | 先交换再累加.(结果在第一个操作数里) |
XLAT | 字节查表转换.----BX指向一张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL) |
输入输出端口传送指令
输入输出端口传送指令 | 描述 |
---|
IN | I/O端口输入. ( 语法: IN 累加器, {端口号│DX} ) |
OUT | I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )输入输出端口由立即方式指定时,其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535. |
目的地址传送指令
目的地址传送指令 | 描述 |
---|
LEA | 装入有效地址.例: LEA DX,string ;把偏移地址存到DX. |
LDS | 传送目标指针,把指针内容装入DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI. |
LES | 传送目标指针,把指针内容装入ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI. |
LFS | 传送目标指针,把指针内容装入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI. |
LGS | 传送目标指针,把指针内容装入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI. |
LSS | 传送目标指针,把指针内容装入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI. |
标志传送指令
标志传送指令 | 描述 |
---|
LAHF | 标志寄存器传送,把标志装入AH. |
SAHF | 标志寄存器传送,把AH内容装入标志寄存器. |
PUSHF | 标志入栈. |
POPF | 标志出栈. |
PUSHD | 32位标志入栈. |
POPD | 32位标志出栈. |
算数运算指令
算数运算指令 | 描述 |
---|
ADD | 加法. |
ADC | 带进位加法. |
INC | 加 1. |
AAA | 加法的ASCII码调整. |
DAA | 加法的十进制调整. |
SUB | 减法. |
SBB | 带借位减法. |
DEC | 减 1. |
NEG | 求反(以 0 减之). |
CMP | 比较.(两操作数作减法,仅修改标志位,不回送结果). |
AAS | 减法的ASCII码调整. |
DAS | 减法的十进制调整. |
MUL | 无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算), |
IMUL | 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算), |
AAM | 乘法的ASCII码调整. |
DIV | 无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算). |
IDIV | 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算). |
AAD | 除法的ASCII码调整. |
CBW | 字节转换为字. (把AL中字节的符号扩展到AH中去) |
CWD | 字转换为双字. (把AX中的字的符号扩展到DX中去) |
CWDE | 字转换为双字. (把AX中的字符号扩展到EAX中去) |
CDQ | 双字扩展. (把EAX中的字的符号扩展到EDX中去) |
串指令
串指令 | 描述 |
---|
MOVS | 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. ) |
CMPS | 串比较.( CMPSB 比较字符. CMPSW 比较字. ) |
SCAS | 串扫描.把AL或AX的内容与目标串作比较,比较结果反映在标志位. |
LODS | 装入串.把源串中的元素(字或字节)逐一装入AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. ) |
STOS | 保存串.是LODS的逆过程. |
REP | 当CX/ECX<>0时重复. |
REPE/REPZ | 当ZF=1或比较结果相等,且CX/ECX<>0时重复. |
REPNE/REPNZ | 当ZF=0或比较结果不相等,且CX/ECX<>0时重复. |
REPC | 当CF=1且CX/ECX<>0时重复. |
REPNC | 当CF=0且CX/ECX<>0时重复. |
无条件转移指令
无条件转移指令(长转移) | 描述 |
---|
JMP | 无条件转移指令 |
CALL | 过程调用 |
RET/RETF | 过程返回 |
条件转移指令
条件转移指令(短转移:-128~127) | 描述 |
---|
JA/JNBE | 不小于或不等于时转移. |
JAE/JNB | 大于或等于转移. |
JB/JNAE | 小于转移. |
JBE/JNA | 小于或等于转移. |
---- | 以上四条,测试无符号整数运算的结果(标志C和Z). |
JG/JNLE | 大于转移. |
JGE/JNL | 大于或等于转移. |
JL/JNGE | 小于转移. |
JLE/JNG | 小于或等于转移. |
— | 以上四条,测试带符号整数运算的结果(标志S,O和Z). |
JE/JZ | 等于转移. |
JNE/JNZ | 不等于时转移. |
JC | 有进位时转移. |
JNC | 无进位时转移. |
JNO | 不溢出时转移. |
JNP/JPO | 奇偶性为奇数时转移. |
JNS | 符号位为 “0” 时转移. |
JO | 溢出转移. |
JP/JPE | 奇偶性为偶数时转移. |
JS | 符号位为 “1” 时转移. |
循环控制指令
循环控制指令(短转移) | 描述 |
---|
LOOP | CX不为零时循环. |
LOOPE/LOOPZ | CX不为零且标志Z=1时循环. |
LOOPNE/LOOPNZ | CX不为零且标志Z=0时循环. |
JCXZ | CX为零时转移. |
JECXZ | ECX为零时转移. |
中断指令
中断指令 | 描述 |
---|
INT | 中断指令 |
INTO | 溢出中断 |
IRET | 中断返回 |
处理器控制指令
处理器控制指令 | 描述 |
---|
HLT | 处理器暂停, 直到出现中断或复位信号才继续. |
WAIT | 当芯片引线TEST为高电平时使CPU进入等待状态. |
ESC | 转换到外处理器. |
LOCK | 封锁总线. |
NOP | 空操作. |
STC | 置进位标志位. |
CLC | 清进位标志位. |
CMC | 进位标志取反. |
STD | 置方向标志位. |
CLD | 清方向标志位. |
STI | 置中断允许位. |
CLI | 清中断允许位. |
伪指令
伪指令 | 描述 |
---|
DW | 定义字(2字节). |
PROC | 定义过程. |
ENDP | 过程结束. |
SEGMENT | 定义段. |
ASSUME | 建立段寄存器寻址. |
ENDS | 段结束. |
END | 程序结束. |
标志处理指令
标志处理指令 | 描述 |
---|
CLC | 进位位置0指令 |
CMC | 进位位求反指令 |
STC | 进位位置为1指令 |
CLD | 方向标志置1指令 |
STD | 方向标志位置1指令 |
CLI | 中断标志置0指令 |
STI | 中断标志置1指令 |
NOP | 无操作 |
HLT | 停机 |
WAIT | 等待 |
ESC | 换码 |
LOCK | 封锁 |
nasm简介
这东西用来执行汇编阶段,将汇编代码转成机器码obj,其实语法非常简单,可以参考nasm官方文档
简单点用的话就是:
nasm -f [输出格式] [依赖文件名称] -o [输出文件名称]
文件格式如elf。
最后
以上就是长情唇膏为你收集整理的汇编语言简介编译流程汇编是什么实模式和保护模式寄存器介绍堆栈模型具体指令nasm简介的全部内容,希望文章能够帮你解决汇编语言简介编译流程汇编是什么实模式和保护模式寄存器介绍堆栈模型具体指令nasm简介所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复