开发者社区> ander.li> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

汇编语言学习

简介:
+关注继续查看

汇编基础

- 80x86 寄存器组(8 位)

  1. AX 累加器用,常用于算术;乘除指令中存放操作数;I/O 指令中与外设传送信息
  2. BX 通用;计算存储器地址时,常用作基址寄存器
  3. CX 通用;保存计数值
  4. DX 通用;作双字长运算时把 DX 和 AX 组合在一起存放,DX 作为高位
  5. SP 堆栈指针,与 SS 联用
  6. BP 基址指针,与 SS 联用
  7. SI 源变址,与 DS 联用
  8. DI 目的变址,与 SS, ES 联用

- 80x86 专用寄存器组

  1. OF 溢出标志
  2. SF 符号标志(为负置 1)
  3. ZF 零标志(为零置 1)
  4. CF 进位标志
  5. AF 辅助进位标志(记录运算时第三位产生的进位值)
  6. DF 方向标志(为 1 时使每次操作后 SI 和 DI 减小)
  7. TF 陷阱标志
  8. IF 中断标志(为 1 时允许 CPU 响应可屏蔽中断请求)

实模式寄存器寻址

16d * 16位段地址 + 16位偏移地址 = 物理<

- 寻址方式

与数据有关

  1. 立即寻址(MOV AL,5)
  2. 寄存器寻址(MOV AX,BX)
  3. 直接寻址(MOV AX, [2000H])
  4. 寄存器间接(MOV AX,[BX])
  5. 寄存器相对(MOV AX,COUNT[SI 或 MOV AX,[COUNT + SI])
  6. 基址变址(MOV AX,[BX + DI] 或 MOV AX,BX)
  7. 相对基址变址(MOV AX, MASKBX 或 MOV AX,MASK[BX + SI] 或 MOV AX,[MASK + BX + SI])
  8. 比例变址(MOV EAX,COUNT[ESI * 4])
  9. 基址比例变址(MOV ECX,EAX)
  10. 相对基址比例变址(MOV EAX,TABLEEBP)

与转移地址有关

  1. 段内直接 NEAR / SHORT
  2. 段内间接 WORD PTR...
  3. 段间直接 FAR PTR...
  4. 段间间接 DWORD PTR...

PS:

  • 操作数的数据类型需要匹配

- 指令系统

1. 数据传送指令

MOV OPRD1,OPRD2
功能:将 OPERD2 赋值给 OPERD1
参数:
  1. OPRD1:寄存器、存储器、累加器
  2. OPRD2:寄存器、存储器、累加器、立即数
  3. OPRD1 与 OPERD2 长度必须一致,即同为8为或16位

PS:

  • 目的操作数不可用立即数和 CS 段
  • 两个操作数中至少一个为寄存器
  • 不允许段寄存器直接传送信息
  • 该指令不影响标志位
MOVSX OPRD1,OPRD2 (x386)
功能:在 MOV 基础上用源操作数填充目的数高位
参数:同 MOV (x386)
MOVZX OPRD1,OPRD2 (x386)
功能:在 MOV 基础上用 0 填充目的数高位
参数:同 MOV
PUSH OPED
功能:将数压栈

下面以16位为例

(SP) = (SP) - 2

((SP) + 1,(SP)) = (SRC)

参数:
  1. OPRD:16位操作数、寄存器、存储器操作数
POP OPRD
功能:将数弹出栈

下面以16位为例

(DST) = ((SP) + 1,(SP))

(SP) = (SP) + 2

参数:同 push
XCHG OPRD1,OPED2
功能:交换数
参数:
  1. 同为寄存器
  2. 寄存器与存储器

2. 算术运算指令

ADD DST,SRC
功能:加法
参数:
  1. DST:被加数
  2. SRC:加数
ADC DST,SRC
功能:带进位加法

(DST)=(DST)+(SRC)+(CF)

参数:
  1. DST:被加数
  2. SRC:加数
  3. CF:进位
INC OPR
功能:自增 1

(OPR)=(OPR)+1

参数:
  1. OPR:被加数
XADD DST,SRC
功能:交换并相加
  1. TEMP=(DST)+(SRC)
  2. (SRC)=(DST)
  3. (DST)=TEMP
参数:
  1. DST:得到相加结果
  2. SRC:得到 DST
SUB DST,SRC
功能:减法
参数:
  1. DST:被减数
  2. SRC:减数
SBB DST,SRT
功能:带借位的减法

(DST)=(DST)-(SRC)-(CF)

参数:
  1. DST:被减数
  2. SRC:减数
  3. CF:借位
DEC OPR
功能:自减 1
参数:
  1. OPR:被减数
NEG OPR
功能:求补

(OPR)= -(OPR)

参数:
CMP OPR1,OPR2
功能:比较,后跟条件转移指令

(OPR1)-(OPR2)

* CMPXCHG DST,SRT
功能:比较并交换
参数:
* CMPXCHG8B DST,SRT
功能:比较并交换 8 字节指令
参数:
MUL SRC
功能:无符号数乘法
  1. (AX)=(AL)*(SRC)
  2. (DX,AX)=(AX)*(SRC)
  3. (EDX,EAX)=(EAX)*(SRC)
参数:
  1. SRC:不能为立即数,无符号
IMUL SRC
功能:带符号数乘法

(类似于 MUL )

参数:
  1. SRC:不能为立即数,有符号
DIV SRC
功能:无符号除法

(类似于 MUL )

参数:
IDIV SRC
功能:带符号除法

(类似于 MUL )

参数:

3. 逻辑运算指令

AND DST,SRC
功能:与
一般用法:
  1. 与自身,得全 1
  2. 与零,取反
  3. 与一,不变
OR DST,SRC
功能:或
一般用法:
  1. 或自身,不变
  2. 或零,不变
  3. 或一,得全 1
NOT OPR
功能:非
XOR DST,SRC
功能:异或
一般用法:
  1. 异或自身,得全 0
  2. 异或零,不变
  3. 异或一,取反
TEST OPR1,OPR2
功能:测试(得到与的结果,置条件码)
一般用法:

执行按位与运算,结果全 0 则 ZF = 1。


4. 移位指令

SHL OPR,CNT
SAL OPT,CNT
功能:逻辑/算术左移

左移右添 0

参数:
  1. CNT:1 或 CL
SHR OPR,CNT
功能:逻辑右移

右移左添 0,CF <- 低位

参数:
SAR OPR,CNT
功能:算术右移

右移左添高位自身,CF <- 低位

参数:
ROL OPR,CNT
功能:循环左移

CF <- 高位

参数:
ROR OPR,CNT
功能:循环右移

CF <- 低位

参数:
RCL OPR,CNT
功能:带进位循环左移

加上 CF 循环左移

参数:
RCR OPR,CNT
功能:带进位循环右移

加上 CF 循环右移

参数:

5. 串处理指令

MOVS DST,SRC
MOVSB DST,SRC
MOVSW DST,SRC
MOVSD DST,SRC
功能:串转移
参数:
CMPS SRC,DST
CMPSB SRC,DST
CMPSW SRC,DST
CMPSD SRC,DST (386)
功能:串比较
参数:
SCAS DST
SCASB DST
SCASW DST
SCASD DST (386)
功能:串扫描

(AL/AX/EAX)-(DST)

参数:
LODS SRC
LODSB SRC
LODSW SRC
LODSD SRC (386)
功能:串读取

(AL/AX/EAX)=(...)

参数:
STOS DST
STOSB DST
STOSW DST
STOSD DST (386)
功能:存入串

(...)=(AL/AX/EAX)

参数:
INS DST,DX
INSB DST,DX
INSW DST,DX
INSD DST,DX (386)
功能:串输入

(...)=(DX)

参数:
OUTS DX,SRC
OUTSB DX,SRC
OUTSW DX,SRC
OUTSD DX,SRC (386)
功能:串输出

(DX)=(...)

参数:
CLD
功能:使 DF = 0
STD
功能:使 DF = 1
REP
功能:前缀,重复
参数:
REPE/REPZ
功能:前缀,相等/为零则重复
参数:
REPNE/REPNZ
功能:前缀,不相等/不为零则重复
参数:

6. 控制转移指令

(以下指令均省略唯一操作数 OPR:转移的目标地址)

<<根据单个标志位的设置情况转移>>

JMP SHORT
JMP NEAR
JMP WORD PTR
JMP FAR PTR
JMP DWORD PTR
功能:无条件转移
  1. 段内直接短/近转移:
    SHORT/NEAR:(IP)=(IP)+ 8/16 位偏移量
  2. 段内间接近转移:
    WORD:(IP)=(EA)
  3. 段内直接远转移:
    FAR:(IP)=OPR 的段内偏移地址
  4. 段内间接远转移
    DWORD:(IP)=(EA)
JZ
JE
转移条件:为零/相等
测试条件:ZF=1
JNZ
JNE
转移条件:不为零/不相等
测试条件:ZF=0
JS OPR
转移条件:为负则转移
测试条件:SF=1
JNS
转移条件:为正
测试条件:SF=0
JO
转移条件:溢出
测试条件:OF=1
JNO
转移条件:不溢出
测试条件:OF=0
JP
JPE
转移条件:奇偶位为 1
测试条件:PF=1
JNP
JPO
转移条件:奇偶位为 0
测试条件:PF=0
JB
JNAE
JC
转移条件:低于(<)或进位为 1
测试条件:CF=1
JNB
JAE
JNC
转移条件:不低于(>=)或进位为 0
测试条件:CF=0

<<比较无符号数根据结果转移>>

JB
JNAE
JC
转移条件:低于(<)或进位为 1
测试条件:CF=1
JNB
JAE
JNC
转移条件:不低于(>=)或进位为 0
测试条件:CF=0
JBE
JNA
转移条件:不高于(<=)
测试条件:CF||ZF = 1
JNBE
JA
转移条件:高于(>)
测试条件:CF||ZF = 0

<<比较带符号数根据结果转移>>

JL
JNGE
转移条件:小于(<)
测试条件:SF||OF = 1
JNL
JGE
转移条件:不小于(>=)
测试条件:SF||OF = 0
JLE
JNG
转移条件:不大于(<=)
测试条件:(SF||OF)||ZF = 1
JNLE
JG
转移条件:大于(>)
测试条件:(SF||OF)||ZF = 0

<<根据单个条件标志,设置目的字节为 1 >>

(以下指令均省略唯一操作数 DST:设置的目标地址)

SETZ
SETE
条件:结果为 0
SETNZ
SETNE
条件:结果不为 0
SETS
条件:结果为负
SETNS
条件:结果为正
SETO
条件:溢出
SETNO
条件:不溢出
SETP
SETPE
条件:奇偶位为 1
SETNP
SETPO
条件:奇偶位为 0
SETC
SETB
SETNAE
条件:低于(<)或进位位位 1 【可用于下面的无符号数比较】
SETNC
SETNB
SETAE
条件:不低于(>=)或进位位为 0【可用于下面的无符号数比较】

<<比较两个无符号数,根据结果设置目的字节为 1 >>

SETBE
SETNA
条件:不高于(<=)
SETNBE
SETA
条件:高于(>)

<<比较两个带符号数,根据结果设置目的字节为 1 >>

SETL
SETNGE
条件:小于(<)
SETNL
SETGE
条件:不小于(>=)
SETLE
SETNG
条件:不大于(<=)
SETNLE
SETG
条件:大于(>)

<<循环>>

LOOP OPR
LOOPZ/LOOPE OPR
LOOPNZ/LOOPNE OPR
循环条件:
  1. 计数器不为 0
  2. 为零或相等
  3. 不为零或不相等
参数:转移目的地址/循环代码段名

<<子程序>>

CALL DST
功能:调用
参数:子程序名
RET
RET EXP
转移条件:无
参数:
  1. EXP:立即数

7. 中断指令

INT
INT TYPE
参数:
  1. TYPE 常数或常数表达式
INTO
中断条件:溢出
IRET
IRETD
转移条件:从中断返回指令(16/32位)

8. 标志处理指令

CLC
功能:CF = 0
CMC
功能:CF = -CF
STC
功能:CF = 1
CLD
功能:DF = 0
STD
功能:DF = 1
CLI
功能:IF = 0
STI
功能:IF = 1

9. 杂项操作

NOP
无操作
HLT
停机
ESC
换码
WAIT
等待
LOCK
封锁
BOUND
界限
ENTER
建立堆栈帧
LEAVE
释放堆栈帧

汇编程序

完整版

DATAS SEGMENT
    ;此处输入数据段代码  
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    MOV AH,4CH
    INT 21H
CODES ENDS
END START

简化版

.MODEL SMALL
.DATA
    ;此处输入数据段代码  
.STACK
    ;此处输入堆栈段代码
.CODE
.STARTUP
     ;此处输入代码段代码
.EXIT
     END

完整版段定义(数据段、堆栈段、代码段)

声明
segmentName SEGMENT [align_type][combine_type][use_type]['class']
    ...
segmentName ENDS
明确关系
ASSUME assignment, ... , assignment
(assignment 即 segmentRegisterName : segmentName 如 DS : DATAS)
声明的其他参数
  1. align_type 定位类型(可选: PARA、 BYTE、 WORD、 DWORD、 PAGE)
  2. combine_type 组合类型(可选: PRIVATE、 PUBLIC、 COMMENT、 AT expression、 MEMORY、 STACK)
  3. use_type 使用类型(可选: USE16、 USE32)
  4. 'class' 类别

简化版定义

.MODEL memory_model[, model options]
参数可选或设置
  1. Tiny 近访问
  2. Small 近访问(常用)
  3. Medium 数据近访问、代码可远访问
  4. Compact 代码近访问、数据可远访问
  5. Large 远访问
  6. Huge 数据段超过 64k,远访问
  7. Flat 允许 32位偏移量(DOS 不支持)
  8. model options 允许用户指定三种选项:高级语言接口、操作系统和堆栈距离

数据定义

  1. DB 一个字节-8
  2. DW 一个字 - 16
  3. DD 双字 - 32
  4. DF 6个字节的字 - 48
  5. DQ 4字 - 64
  6. DT 10字节 - 80

操作数定义

  1. DUP(?) 占位(保留位);可嵌套
  2. 字符串
  3. 立即数

表达式赋值(EQU)

Expression_name EQU Expression

地址计数器

  1. $ 获取当前地址计数器的值
  2. ORG 设置当前地址计数器的值
  3. EVEN 使下一个变量或指令开始于偶数字节地址
  4. ALIGN 使下一个变量或指令开始于 4 的倍数字节地址

基数控制

.RADIX expression

操作项

  1. +、-、*、/ 和 MOD 基本运算
  2. SHL、 SHR 移位
  3. EQ、 NE、 LT、 GT、 LE、 GE 关系操作符
  4. TYPE 变量类型字节数
  5. LENGTH 变量单元数
  6. SIZE 为 LENGTH 和 TYPE 的乘积
  7. OFFSET 变量或标号偏移地址
  8. SEG 变量或标号段地址
  9. PTR
  10. SHORT
  11. THIS
  12. HIGH
  13. LOW
  14. HIGHWORD
  15. LOWWORD

输入输出程序设计

直接存储器存取方式(DMA、 其他CPU传输方式:查询、中断)

  1. DMA 向 CPU 发出 HOLD 信号,请求使用总线
  2. CUP 发出响应信号 HOLD 给 DMA,并让出总线
  3. 传输数据的地址通过地址总线发出
  4. 传输的数据字节通过数据总线传送
  5. 地址寄存器 +1,指向下一个要传送的字节
  6. 字节计数器 -1
  7. 如果字节计数器非 0, 转向第 3 步
  8. 否则,DMA 撤销总线请求信号 HOLD,传送结束

I/O 端口

三种寄存器

  1. 数据寄存器 - 用于数据缓冲
  2. 状态寄存器 - 用于保存设备和接口的状态信息、供 CPU 对外设进行测试
  3. 命令寄存器 - 用于保存 CPU 发出的命令以控制接口和设备的操作

中断传送

硬件中断

  1. 可屏蔽 - 8259 控制位(中断允许位 IF)
  2. 非屏蔽 - 2#

软件中断

  1. INT
  2. CPU 某些错误引起
  3. DEBUG - 单步、 断点

中断过程

  1. 取中断类型号 N
  2. 标志寄存器 FLAGS 内容入栈
  3. 当前代码段寄存器 CS 内容入栈
  4. 当前指令计数器 IP 内容入栈
  5. 禁止硬件中断和单步中断 IF=0,TF=0
  6. 从中断向量表中取 4 N 的字内容送 IP,取 4 N + 2 中的字内容送 CS
  7. 转中断处理程序

BIOS 和 DOS 中断(略)

总结

指令系统

  1. CL * 开头的为 clear (复位)对应的标志位(CLD, CLC, CLI, ...)
  2. ST * 开头的为 set (置位)对应的标志位(STD, STC, STI ...)
  3. 无符号数比高低用 A B (above, below)
  4. 有符号数比大小用 G L (great, LESS)

地址疑问

  1. IP 总是指向 CS (代码段)将要执行的(下一行)代码的地址
  2. SP 总是指向刚 push 进去的内容所处位置
  3. DBDW 变量的 SI 偏移量不同(1、 2)

程序设计

子程序传参三种方法:

  1. 寄存器(适用于少变量)
  2. 变量(仅限于同一源文件)
  3. 地址表(仅限于同一模块)
  4. 堆栈或参数地址(适用于多模块)

进制转换

  1. 输入二进制:边存储边左移位
  2. 输入十进制:乘上权值(10)再累加
  3. 输入十六进制:高于 9 则转换,乘上权值(16)再累加
  4. 输出二进制:边左移位边输出
  5. 输出十进制:除法并输出模 10 的值
  6. 输出十六进制:除法并输出模 16 的值(注意转换)

涉及算法

  1. 冒泡排序
  2. 折半查找

CPU与外设传送数据方式

  1. DMA --直接存储器存取
  2. 查询
  3. 中断

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
汇编语言学习 下
汇编语言学习笔记 下
0 0
汇编语言学习 上
本文是介绍汇编语言的基本组成和基本齐全的指令,以及帮助理解这些的背景知识 包括寄存器,汇编语言基本组成部分,数据传送指令,寻址指令,加减法指令,堆栈,过程,条件处理,整数运算
0 0
【汇编语言王爽】学习笔记p54-p79(下)
【汇编语言王爽】学习笔记p54-p79
0 0
【汇编语言王爽】学习笔记-p40-p54
【汇编语言王爽】学习笔记-p40-p54
0 0
【汇编语言王爽】学习笔记p54-p79(上)
【汇编语言王爽】学习笔记p54-p79
0 0
一片文章带你了解汇编语言
一片文章带你了解汇编语言
0 0
汇编语言之基础知识
汇编语言之基础知识
0 0
汇编语言(2)
汇编语言 向屏幕输出文字 向屏幕输出需要向显示缓冲区写数据(在dosbox中在内存的其实位置是0b800h:0000h) 输出的一个字符其实占用的是两个字节(一个字单位), 因为我们不仅要输出一个8位的ASCII, 还要输出该字符的属性, 包括高亮, 颜色, 底色等, 这些有另一个8位决定, 通过...
597 0
+关注
ander.li
不熬夜的程序员....o(* ̄︶ ̄*)o
文章
问答
文章排行榜
最热
最新
相关电子书
更多
为什么要学函数式编程?
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载