相应知识总结于清华大学出版社王爽著汇编语言一书
课程学习:汇编语言王爽第四版及练习答案
我使用的配套工具(MASM5.0,DOSBOX,VIM编辑器)
MASM提供的是阿里网盘,提取码:nfz4
MASA5.0
DOSBOX
VIM编辑器
亦可使用汇编模拟软件emu8086,在一定程度上可以避免修改系统关键位置导致的系统损坏,在此不提供下载地址。
第一章 基础知识
程序语言的发展:
检测点1.1
(1)13
(2)1024,0,1023
(3)8192,1024
(4)2^30
2^20
2^10
(5)2^6,1,16,4
(6)1,1,2,2,4
(7)512,256
(8)二进制
(1)8 KB = 8*2^10 B = 2^13 B,即有13根地址总线
(2)1 KB = 2^10 B
(3)1 KB = 2^10*8 bit
(4)1 GB = 2^10 MB,1 MB = 2^10 KB,1 KB = 2^10 B(byte)
(5)寻址能力 = 2^地址总线 B,经过以上单位换算
(6)8根数据总线 = 1 B,经过单位换算
(7)读取次数 = 将要读取的数据大小/单次可传送的数据
第二章 寄存器
通用寄存器
AX:(Accumulator Register,累加寄存器)储存累计相加数据的数据寄存器
BX:(Base Register,基地址寄存器)大多用于储存偏移地址
CX:(Count Register,计数寄存器)记录循环次数和作为跳转条件,位操作指明移位位数
DX:(Data Register,数据寄存器)储存累计乘除的数据寄存器,也可用于存放I/O端口地址
MOV指令(汇编指令不分大小写)
16进制数末尾有H,例如:FH
mov 寄存器,立即数
例如:mov ax,100H,mov ax,0B800H
注:十六进制以字母开头的立即数必须在最前端加一个0,例如:mov ax,0ffffh,否则编译器无法编译通过。
ADD指令
add 寄存器,立即数
add 寄存器,寄存器
例如:add ax,bx。(ax的数值+bx的数值)的结果给ax(离add最近的寄存器)
十六进制与二进制转化
检测点2.1
(1)注:寄存器中的值以二进制表示,便于观察使用十六进制
AX = F4A3H
AX = 31A3H
AX = 3123H
AX = 6246H
BX = 826CH
CX = 6246H
AX = 826CH
AX = 04D8H 进位被在其他寄存器中记录
AX = 0482H
AX = 6C82H
AX = D882H
AX = D888H
AX = D810H 同上,al中的进位也不会进入ah
AX = 6246H
一种描述物理地址的方法:物理地址 = 段地址*16+偏移地址
段地址:20H
偏移地址:0
定位物理地址(以十六进制表示,段地址乘以16相当于后面加个零):200H或可以写成"段地址:偏移地址"的形式:20:0(物理地址等同于0:200–>此时的段地址是设为0,偏移地址200H,即两者表示同一物理地址,不同写法而已。)
甚至你可以设置段地址为1,2,3…并将偏移地址对应设置为199H,198H,197H…它们所代指的物理地址均是200H。
检测点2.2
(1)00010H,1000FH
(2)1001H,2000H
段地址<1001H或>2000H时
解:(1)CPU最小寻址为:段地址16,偏移地址为0,即00010H
最大寻址为:段地址16,偏移地址为0FFFFH,即1000FH
(2)先考虑偏移地址为0时,段地址最大,为2000H,此时段地址16便是内存物理地址20000H。
再考虑段地址最小,偏移地址最大,本应是0FFFFH,但注意,段地址16后最后一位是0,物理地址最后一位也是0,所以偏移地址最高只能为0FFF0H,故段地址为
20000H-0FFF0H=10010H,故段地址1001H
第一,由上可知在偏移地址达到此题对应的最大值时,段地址最小不低于1001H。
第二,偏移地址不可能是负值,自然段地址(2000H)大于物理地址(20000H)时就不可能寻到l了。
代码段寄存器CS:IP
代码段寄存器:指令指针寄存器
段寄存器:偏移地址
根据CS:IP指向的内存读取指令进入指令缓冲区
IP增加
执行指令
跳转指令 jmp
jmp 段地址:偏移地址
例如:jmp 0:200H
将CS设置为该段地址(0),IP设置为该偏移地址(200H)–>即直接定位到指定内存位置的代码开始运行,指定内存位置可以是该程序中任意一个可执行指令的位置。
jmp 某一合法寄存器
例如:jmp ax
将IP设置为该寄存器的值,保持原CS不变。
检测点2.3
mov ax,bx ;IP+2
sub ax,ax ;IP+2
jmp ax ;IP+2
;IP = ax
共4次,最后IP = AX
第三章 寄存器(内存访问)
数据段寄存器DS和[address]
ds:[address]
数据段寄存器:偏移地址
例如所需定位的数据段在10000H,就可以这样定位,并读取其中数据放在ax中:
mov ax,1000
mov ds,ax
mov ax,ds:[0] ;这里用目的地是ax,所以mov指令读取了1个字(16位)
SUB
add和sub相比mov指令多了一项禁忌:不能对段寄存器做任何操作
add 相加,结果放在离add指令最近的寄存器或内存单元中
sub 相减,结果放在离sub指令最近的寄存器或内存单元中
检测点3.1
(1)AX=2662H
BX=E626H
AX=E626H
AX=2662H
BX=D6E6H
AX=FD48H
AX=2C14H
AX=0000H
AX=00E6H
BX=0000H
BX=0026H
AX=000CH
(2)
①mov ax,6622h
jmp 0ff0h:0100h
mov ax,2000h
mov ds,ax
mov ax,[0008]
mov ax,[0002]
②CS=2000H,IP=0,AX=6622H
CS=0FF0H,IP=0100H
CS=0FF0H,IP=0103H,AX=2000H
CS=0FF0H,IP=0105H,AX=2000H,DS=2000H
CS=0FFFH,IP=0108H,AX=C389H
CS=0FFFH,IP=010BH,AX=EA66H
③有,但程序本身也是数据,只是在特定信号下,计算机读取程序和数据的方式不同。
栈 LIFO(last in first out 后进先出)
栈操作都是以字为单位
栈空间就是一段普通的内存空间,内存空间是连续的,CPU并不会知道你设置的栈空间栈顶和栈底,所以会出现栈超界问题。
定义10010H~1001FH内存空间为栈段
mov ax,10010h
mov ss,ax
mov sp,0fh