8086相关

16位

# PE结构
# 1字{word}=2B
# 段地址(CS) * 16 + 偏移地址(IP) = 实际内存地址
# 段寄存器不能直接赋值,需要用通用寄存器
# 栈push,pop只是改变sp,范围0~FFFFH,最大64kB
# 程序内存位置ds:0,开始是PSP:大小256字节,程序用来与dos通信的端口
# debug时,执行到int 21H用p命令
# bx可以作为数据段偏移地址
# cs一开始作为程序机器码的字节长度,可以作为loop循环条件
# 安全空间:0:200~0:2FF
# 用栈暂时存储数据
# 立即数在指令缓冲器里面
# 栈只对字操作
# 结构体:bx定位结构体位置,idata定位某一个数据项,si定位数据项中的元素位置:ds:bx.idata[si]
# 不能直接修该cs的值,要用jump
# mov不能进行存储器->存储器
##### 显存
# B8000H~BFFFFH共32KB,显存(row)25x(col)80,每屏可显示4000B,每行160B,每列25B
# 偶地址存放字符,奇地址存放颜色属性
# 7             6   5   4         3            2   1   0
# BL(闪烁)     (R   G   B)背景     I(高亮)     (R   G   B)前景
# nop:占用一个字节位置
# 123H,111B
# BX与BP是基址,DI与SI是变址
# 不会溢出的除法
# inc,loop,not不会影响CF的值
# 无符号数比较大小考虑:ZF{零标志位},CF{进位(借位)标志位}
# 有符号数比较大小考虑:ZF{零标志位},OF{进位(借位)标志位},SF(符号标志位)
# ss与sp的设置不会被中断
# 端口:寄存器

寄存器

# 通用寄存器:
- AX{accumulator}:累加寄存器
- BX{base}:基址寄存器
- CX{count}:计数寄存器
- DX{data}:数据寄存器
# AX,BX,CX,DX(16位寄存器)
* AH{high}(高8位寄存器)
* AL{low}(低8位寄存器)
# 与BX同作用
- DI
- SI
# 段寄存器:
- CS{code segment}:代码段寄存器
- DS{data segment}:数据段寄存器
- SS{stack segment}:栈段寄存器
- ES{extra segment}:附加段寄存器
# 偏移地址
- IP{instruction pointer}:CS的偏移地址
- SP{stack pointer}:SS的偏移地址
- BP{base pointer}:栈基址寄存器
- 只有四个寄存机可以内存单元寻址:DS:[BX],SS:[BP],DI,SI
- BX与BP,DI与SI不能同时出现
# 标志寄存器
- FLAG[运算时修改]
- 1,3,5,12,13,14,15位没有被使用
- 0{carry flag}(CF):进位(借位)标志位[无符号数是否进位(借位)]
- 2{parity flag}(PF):奇偶标志位[是否有偶数个1]
- 4(auxiliary carry flag)(AF):辅助进位标志[4位是否进位(借位)]
- 6{zero flag}(ZF):零标志位[是否为0]
- 7{sign flag}(SF):符号标志位[是否为负数]
- 8{trap flag}(TF):跟踪标志位[是否是单步状态]
- 9{interrupt enable flag}(IF):中断允许标志位[中断是否被允许]
- 10{direction flag}(DF):方向标志位[是否递增] // DF=0,++SI,++DI;DF=1,--SI,--DI;
- 11{overflow flag}(OF):溢出标志位[有符号数是否溢出]

注意点

########## MASM中
# 不能直接将立即数赋值给段寄存器
mov ax,1000H
mov ds,ax
----------
# 不能直接[1]获取数据内存位置,[0]可以
mov bx,1H
mov ds,[bx]
# 或直接
mov ax ds:[1]
----------
# cs:[0];ds:[0];ss:[0];es:[0];
----------
# 立即数不能以字母开头
mov ax,0FFFFH
----------

汇编指令

# adc ax,bx // ax = ax + bx + CF(进位/借位)
# sbb ax,bx // ax = ax - bx - CF(进位/借位)
# cmp ax,bx // 只修改标志寄存器
# cmps // 串比较
# scas // 串查找
# lods // 串载入
# stos // 串存储
----------无符号数
# below...之下;above在...之上;equal与...相等;与cmp共用
# je relative_flag; // ZF=1,即相等跳转
# jne relative_flag // ZF=0,即不相等跳转
# jb relative_flag; // CF=1,即小于跳转
# jnb relative_flag // CF=0,即不小于跳转
# ja relative_flag; // CF=0&&ZF=0,即大于跳转
# jna relative_flag // CF=1||ZF=1,即不大于跳转
----------
# rep // cx==0;退出,cx-=1;
# repe // cx!==0||ZF==0;退出,cx-=1;
# repne // cx!==0||ZF==1;退出,cx-=1;
# rep movsb // {mov string byte};传送cx个字节;(源地址)ds:si,(目的地址)es:di会根据DF{方向标志位}自增自减
# rep movsw // {mov string word};传送cx个字;(源地址)ds:si,(目的地址)es:di会根据DF{方向标志位}自增自减
# cld // {clear DF};DF=0
# std // {set DF};DF=1
# sti // IF=1
# cli // IF=0
# clc // CF=0
# stc // CF=1
# stc // CF=!CF
# hlt // 停机
# wait // 等待
# esc // 转移
# lock前缀 // 封锁
----------
# add ax,0001H <--> ax += 0001H
# sub ax,0001H // ax -= 0001H
// 8x8;16x16;
# mul byte ptr ds:[0] // 被乘数:al;积:ax;
# mul word ptr ds:[0] // 被乘数:ax;积:(高八位)dx,(低八位)ax;
# imul // 有符号乘法
// 32/16;16/8;
# div byte ptr ds:[0] // 被除数:ax;商:al;余数:ah;
# div word ptr ds:[0] // 被除数:(高八位)dx,(低八位)ax;商:ax,余数:dx;
# idiv // 有符号除法
# test // 监测是否为0
----------
# mov ax,0001H <--> ax = 0001H
# mov ax,ds <--> ax = ds{数据段}
# mov ax,[0] <--> ax = [DS:0]{数据段地址:偏移地址}
# mov ax,[bx+200]
# mov ax,200[bx]
# mov ax,[bx].200
# mov ax,[bx][di]
# mov ax,200[bx+di]
# mov byte ptr ds:[0],1 // 指明数据长度01H
# mov word ptr ds:[0],1 // 指明数据长度0001H
----------
# jmp 2000:0000 <--> 段地址(CS):偏移地址(IP)
# jmp ax <--> ip = ax // 绝对跳转
# jmp relative_flag // 修改IP,相对跳转
# jmp word ptr [0] // 修改IP,把内存的字数据当成地址跳转
# jmp dword ptr [0] // 修改CS,IP,把内存的字数据当成地址跳转
# jmp short relative_flag // 短转移,修改IP,范围-128~127(1Byte),相对跳转,0表示本位置
# jmp near relative_flag // 近转移,修改IP,范围-32768~32767(1Byte),相对跳转
# jmp far ptr relative_flag // 修改CS,IP,范围大,相对跳转
----------
# push ax <--> sp -= 2; ss:sp = ax;
# push ds
# push [0] <--> push ds:0
# pop ax <--> ax = ss:sp; sp += 2;
# pop ds
# pushf // push 标志寄存器(可以入栈修改寄存器的值)
# popf // pop 标志寄存器
# iret // {interupt return};pop ip;pop cs;popf;
# int 21H // {interupt 8位};push popf;push cs;push ip;
----------
# inc ax // ++ax
# dec ax // --ax
# loop relative_flag // 范围-128~127(1Byte),类似goto;cx-=1;cx不为0跳到relative_flag:
# mov ax,offset start // 获取start的偏移地址,cs:[offset start]是start处指令
# jcxz relative_flag // cx为0跳到relative_flag:
----------
# db 12H,34H <--> {define byte}:定义字节数据
# db 'abcd' <--> 定义字符串
# dw 1234H,0923H <--> {define work}:定义字型数据
# dd 00000001H <--> {define dwork}:定义双字型数据
# db 3 dup('a','bc') <--> db 'abcabcabc' //  重复3次'abc'
----------
# and ax,0123H <--> 按位与
# or ax,0123H <-->  按位或
# xor ax,ax // 异或,清0
----------
# ret // pop ip;
# retf // pop ip;pop cs;
# call relative_flag // push ip;jmp relative_flag;修改ip;相对位移,范围-32768~32767(1Byte)
# call far relative_flag // push cs;push ip;jmp far relative_flag;修改ip;相对位移
# call ax // push ip;ip = ax;绝对跳转
# call word ptr [bx] // push ip;jmp word ptr [bx];
# call dword ptr [bx] // push cs;push ip;jmp dword ptr [bx];
----------
# in al,60H // 从60端口读取(byte)到al
# out 60H,al // 将al输出到60H端口
----------
# shl al,1 // {shift left}:逻辑左移,移动位数大于1时,位数放到cl中
# shr al,1 // {shift right}:逻辑右移,移动位数大于1时,位数放到cl中
# sal // 算数左移
# sar // 算数右移
# rol // 循环左移
# ror // 循环右移
# rcl // 带CF循环左移
# rcr // 带CF循环右移
# xchg ax,bx // 交换寄存器内容

伪指令

shell # 控制操作系统的命令集合
assume cs:xxx1 # 假设代码段xxx (就可以用数据标号访问数据)
assume ds:xxx1 # 假设数据段xxx (就可以用数据标号访问数据)
string db 'aaa' # 定义string
string[0] # 获取字符
str dw string # string(偏移地址)翻译为一个数
str dd string # string(段地址+偏移地址)翻译为一个数
----------
xxx segment # xxx段的开始
XXX: # 程序入口
xxx ends # xxx段的结束
# 程序返回(执行21H号中端,第4cH个子程序)
mov ah,4cH
int 21H
end XXX # 程序结束

debug指令

r # 查看寄存器内容
r ax # 修改寄存器内容
t # 执行一条机器指令
d 2000:0000 # {段地址:偏移地址}查看内存中的内容
e # 改写内存中的内容
u 2000:0000 # {段地址:偏移地址}将内存中的机器指令翻译成汇编指令
a # 以汇编指令的格式写入一条机器指令
q # 退出
p # 停止,跳出循环
g # 直接运行到某个位置等待执行(跳转断点)
###
B810:0 # 显卡位置

中断

# push flag;TF=0,IF=0;push cs;push ip;
# IF=0
# 中断向量表(8位索引),共256项
# 在内存0000:0000~0000:03FF共1024个单元
# 数据应放到代码段
mov cx,offset do0end - offset do0
do0:
	// ...
	mov ax,4c00H
	int 21H
do0end: 
	nop
# ----------
push bp
mov bp,sp
// ...
pop bp
# 不可屏蔽终端类型码都是2
# 0040:17(键盘状态字节)
# ----------
# 键盘按下(通码)与松开(断码)都会产生一个扫描码
# 断码 = 通码 + 80H
# 按状态键不会存储到键盘缓冲区,只会改变键盘状态字节
int al,60H # 读出键盘输入扫描码
int 9 # 从端口60H读取扫描码,得出对应字符Ascii码,键盘缓冲存储或键盘状态改变
int 16 # 读取键盘缓冲区(ah=0) ==> ah(扫描码),al(字符Ascii码)
int 13 # 对磁盘进行读写(读:ah=2),al:读取扇区数,ch:磁道号,cl:扇区号,dh:磁头好,dl:驱动号

COMS RAM

# 70H为地址端口,71H为数据端口
# 秒:00H;分:02H;时:04H;日:07H;月:08H;年:09H;BCD码(4位1个十进制数)存放
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值