总览
在doxbox上体验了一下16位DOS系统上写MASM/NASM格式汇编。
====> 8086cpu架构以及dosbox debug教程
====> 视频教程
cpu总线基本的有:
- 地址总线:寻址范围
- 数据总线:数据传输速度
- 控制总线:是一类控制线的总称
我们常说的多少位cpu,指的是数据总线宽度,以及寄存器最大位数。比如32位cpu,那么数据总线宽度为32位,寄存器最大为32位。注意现代的64位cpu,数据总线为64位,但是地址总线小于64位,因为内存没有这么大所以寻址范围不用这么大。
DOSBox每次启动时,都要先mount一下,比较麻烦。可以在dosbox配置文件中添加启动命令来解决该问题。
mount 主要用于将主机(运行 DOSBox 的计算机)的文件系统目录映射为 DOSBox 模拟环境中的虚拟驱动器,使得 DOSBox 可以访问主机上的文件和文件夹。
双击DOSBOX-0.74 -> DOSBox 0.74-3 Options.bat
添加:
x86汇编语法:
https://zhuanlan.zhihu.com/p/443522525
汇编文件.S和.asm的区别:
.S
汇编文件常见于 Unix 或类 Unix 系统,常由高级语言经预处理器处理后生成,也可手动编写,多遵循 AT&T 汇编语法,编译时需先经预处理器处理再由汇编器汇编,且在系统软件和嵌入式开发中应用较多;.asm
汇编文件在各种平台都有应用,尤其是 Windows 平台,一般为纯粹手动编写的汇编代码文件,多遵循 Intel 汇编语法,可直接用汇编器汇编,常用于底层驱动程序编写、游戏开发中的性能关键部分及逆向工程等领域。
MASM格式:
https://blog.csdn.net/qq_43722079/article/details/107690205
NASM格式:
; 标准EXE程序模板
segment code ; 代码段定义
..start: ; EXE程序入口点
mov ax, data
mov ds, ax ; 初始化数据段
mov ax, stack
mov ss, ax ; 初始化堆栈段
mov sp, stacktop
; 主程序逻辑
mov ax, 1
mov bx, 2
add ax, bx
; 退出程序
mov ax, 4C00h
int 21h
segment data ; 数据段
; 数据定义区
segment stack stack
resb 64 ; 64字节堆栈
stacktop:
用NASM编译时报错dosbox报错load error no dpmi
解决方法:下载cwsdpmi文件,和nasm放到一起
https://github.com/jayschwa/cwsdpmi
编译.exe格式文件(包含重定位信息,dos中还有.com这种简单的不包含重定位信息的可执行文件格式)
- 编译:
nasm -f obj prog.asm -o prog.obj
- 链接:
link prog.obj;
- 运行:
prog.exe
dosbox下debug
可以通过该模式快速验证汇编命令
debug
mov ax,1
mov bx,2
add ax,bx
这样不用写完整的汇编格式
也可以debug b.exe
来调试某个可执行文件。
dosbox教程
https://blog.csdn.net/weixin_47586883/article/details/109229208
一.讲解debug的常用操作
二.讲解汇编中的基本指令(穿插编写简单的小程序)
一. 讲解debug的常用操作
(大小写都行)
1.-a
输入汇编代码
eg:mov ax,1000h
2.-t
单步执行CS:IP指向的指令
执行指令后显示寄存器中的内容
如果要一次性执行多条:
-t 100:执行100条
3.-r
显示所有寄存器内容
eg:-r ax
: 1000
显示ax的内容,可以修改为1000也可以不修改按回车
-rf
显示标志位内容 可以修改也可以回车不修改
4.-d
默认显示ds段的指定内容
eg:-d 100 110
显示ds段偏移地址100-110的存储器内容
-d 100
显示ds段偏移地址100-180的存储器内容
-d ss:100 110
显示ss段偏移地址100-180的存储器内容
5.-e
修改指定地址中的内容
eg:-e ds:100 3f,4f,5f
-d 100 102
修改ds段100-102的内容(一并修改)
-e ds:100
逐一修改,空格下一个,回车结束
6.-q
退出指令
二.讲解汇编中的基本指令
一.数据传送类指令
1.数据传送mov
①立即数传送给寄存器和存储器
eg:mov ax,1000h——16位传送寄存器
mov bl,05h——8位传送寄存器
mov [bx],2000h——错误 传送给存储器
因为mov需要指定数据位数:mov word ptr [bx], 2000
mov ds,100h 错误 立即数不能送给段寄存器
mov ax,100h
mov ds,ax
②寄存器内部互传
eg:mov ax,bx ——内部互传
mov ah,al
mov ds,bx——通用寄存器传给段寄存器
mov ds,ss 错误,段寄存器不能互传
mov cs,ax 错误,程序段cs不能作为目的操作数
③寄存器和存储器互传
eg: mov ax,[bx]
mov [bx+si],ax
mov dx,es:[si]
mov [bx],[si] 错误 存储器之间不能互传
(传送不影响标志位)
2.交换指令xchg
①通用寄存器之间交换
xchg ax,bx
xchg al,ah
②存储器和通用寄存器
xchg ax,[bx][si]
xchg ds:[di+si],ax
xchg ds,ss 错误,段寄存器不能交换
xchg ax,1000h 错误,立即数不能交换
xchg [ax],[bx] 错误,寄存器之间不能交换
3.栈操作指令push pop
执行一个小程序:将ff11h 和 ccddh 两个字压入堆栈
然后将ccddh弹出堆栈
‘
mov ax,ff11h
push ax
mov ax,ccddh
push ax
pop ax
4.地址传送指令
①装入有效地址lea
lea cx,2000h[bx][si]
②装入地址les lds/
les cx,2000h[bx][si]
lds cx,2000h[bx][si]
高16位送
es或者ds
5.输入输出指令
内部寄存器只能用ax和al
①输入
in al,20h
in ax,dx
②输出
out 20h,al
out 800h,ax 错误,高于8位的端口地址
需要间接寻址
mov dx,800h
out dx,ax
6.标志位传送指令
①取标志位指令
lahf;
sf zf af pf cf送到ah的7 6 4 2 0位
②存储标志位指令
sahf;
与lahf送的方向相反
③进栈
pushf;
标志寄存器16位全部压入堆栈
④出栈
popf
弹出一个字的内容到标志寄存器fr
7.换码指令
xlat(将ds:[bx+al]的存储单元内容送到al)
二.算术运算类指令
1.加减法指令
与mov格式类似
①不带进位add sub 带进位cf adc sbb
add ax,1000h——立即数加上寄存器
add [bx],500h——立即数加上存储器
add/sub ax, 200h[di]——存储器加上寄存器
add [ax],[bx]错误
add 1000h,ax错误
②加1减1
inc ax—— 寄存器
dec [bx]—— 存储器(也会报错)
inc 1000h错误
③比较指令
cmp ax,bx
对于无符号数,cf=0即没有借位,ax大于等于bx。zf=1则
两个数相等;cf=1是即有借位,ax小于bx
对于有符号数,of与sf相同时,ax大于bx,of与sf不同时,
ax小于bx
④求补指令
neg bx
0-操作数
2.乘法指令
①无符号数乘法
mul cx
mul [cx]
mul 1000h 错误,不能为立即数
结果送到ax或者dx和ax
②有符号数乘法
imul cx
3.除法指令
①无符号数除法
div cx
div [cx]
div 1000h 错误
结果的商送到al或者ax,余数送到ah或者dx
②有符号数除法dic
idiv cx
余数的符号和被除数符号一致
③扩展指令
cbw 8位扩展为16位 al的符号位扩展到ah
cwd 16位扩展为32位 ax的符号位扩展到dx
4.压缩型bcd码调整指令
加法:daa 减法:das
非压缩型bcd码调整指令
加法:aaa 减法:aas
乘法:aam 二进制->十进制
除法:aad bcd码->二进制
实现程序:计算(1234h+345h*12h-2363h)/96h的bcd码结果
345h*12h=3adah
1234h+3adah=4d0eh
4d0eh-2363h=29abh
29abh/96h=47h=64+7=71
三.逻辑类指令
1.逻辑与
and ax,ffffh
2.逻辑或
or ax,0000h
3.逻辑异或
xor al,al——清零
4.逻辑取反
not ax
5.测试指令
test ax,1111h——不送到ax,仅仅改变标志位
四.移位指令
1.移位指令
①.逻辑左移shl
shl ax,4
最低位补0,最高位进入cf
②.逻辑右移shr
shr ax,4
最高位补0,最低位进入cf
③.算术左移sal
最低位补0,最高位进入cf
④.算术右移sar
最高位送回符号位,最低位进入cf
2.循环移位指令
①不带进位的循环左移和循环右移
rol ror
②带进位的循环左移和循环右移
rcl rcr
五.跳转指令
jmp 1111
条件跳转:
jc jnc jne jnz je jz js jns