《汇编语言》(王爽)读书笔记

时间:2022-06-04 12:39:44

第一章 基础知识
◎汇编语言由3类指令组成
汇编指令:机器码的助记符,有对应机器码。
伪指令:没有对应机器码,由编译器执行,计算机并不执行
其他符号:如+-*/,由编译器识别,没有对应机器码
◎一个CPU有n根地址线,则可以所这个CPU的地址线宽度为n,这样的CPU最多可以寻找2的n次方个内存单元。
◎ 1K=2^10B 1M=2^20B 1G=2^30B
◎8086 CPU地址总线宽度为20,寻址范围为00000~FFFFF
00000~9FFFF 主存储器地址空间(RAM)
A0000~BFFFF 显存地址空间
C0000~FFFFF 各类ROM地址空间

第二章 寄存器(CPU工作原理)
◎16位结构描述了一个CPU具有下面几个方面的结构特性
运算器一次最多可以处理16位的数据
寄存器的最大宽度为16位
寄存器和运算器之间的通路为16位
◎8086有20位地址总线,可以传送20位地址,达到1M的寻址能力。采用在内部用两个16位地址合成的方法来形成一个20位的物理地址
◎物理地址 = 段地址 × 16 + 偏移地址
◎在编程是可以根据需要,将若干地址连续的内存单元看作一个段,用段地址×16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址位16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB
◎8086有四个段寄存器 CS、DS、SS、ES
◎CS为代码段寄存器,IP为指令指针寄存器。任意时刻,设CS中内容为M、IP中内容为N,8086CPU从内存M×16+N读取一条指令执行
◎不能用mov修改CS、IP,因为8086CPU没有提供这样功能,可用指令JMP 段地址:偏移地址。JMP 2AE3:3 JMP AX 修改IP

第三章 寄存器(内存访问)
◎DS数据段寄存器。不能将数据直接送入段寄存器,所以『MOV DS, 1』不正确
◎字在存储时要两个连续的内存单元,低位在低地址,高位在高地址
◎[address]表示一个偏移地址为address的内存单元
◎SS:SP指向栈顶元素
◎PUSH AX:(1)SP = SP - 2;(2)AX送入SS:SP
◎POP AX:(1)SS:SP送入AX;(2)SP = SP + 2
◎PUSH/POP 寄存器
PUSH/POP 段寄存器
PUSH/POP 内存单元

第四章 第1个程序
◎可执行文件包含两部分:程序和数据,相关的描述信息
◎程序加载后, ds中存放这程序所在内存区的段地址,这个内存区的偏移地址为0,策程序所在的内存区的地址为ds:0;这个内存区的前256个字节中存放的是PSP,dos用来和程序进行通信。从256字节处向后的空间存放的是程序。

第五章 [BX]和loop指令
◎[BX]表示一个内存单元,它的段地址在ds中,偏移地址在bx中。MOV AX,[BX] MOV AL,[BX] MOV [BX],AX
◎loop要进行两步操作,CX=CX-1;判断cx中值,不为零则转至标号处执行程序,为零则向下执行。
◎masm将指令 mov ax,[0] 当作 mov ax,0 处理
解决方法可以为 mov bx,0 使用寄存器
mov ax,[bx]
或 mov ax,ds:[0] 直接给出段地址所在的段寄存器
◎loop中不可使用 mov [cx],cx

第六章 包含多个段的程序
◎dw 定义字型数据
◎end 标号 定义程序入口点
◎定义多个段,同定义代码段相同。定义仅仅是为了程序阅读方便
◎assume cs:code,ds:data,ss:stack是伪指令,将定义的具有一定用途的段和相关的寄存器联系起来
◎对于段,如果数据占N个字节,则程序加载后实际占有空间为:(N/16+1)*16,N的16整数

第七章 更灵活的定位内存地址的方法
◎and 按位与 and al, 0EFh
◎or 按位或 or al, 20h
◎字母大小写转换:
大写(xx0x xxxx) and al, 0EFh
小写(xx1x xxxx) or al, 20h
◎mov ax,[200+bx] == mov ax,[bx+200] == mov ax,200[bx] == mov ax,[bx].200 段地址为ds,偏移地址为bx+200
◎si和di示8086CPU中和bx功能相近的寄存器,si和di不能分成两个8位寄存器来使用
◎一般来说,在需要暂存数据的时候,都应该使用栈

第八章 数据处理的两个基本问题
◎bx,si,di,bp
1。在8086CPU中,只有这4个寄存器可以用在[...]中来进行内存单元的寻址
正确:mov ax,[bx] | mov ax,[bp]
错误:mov ax,[cx] | mov ax,[dx] | mov ax,[ax] | mov ax,[ds]
2。在[...]中,这4个寄存器可以单个出现,或只能以四种组合出现:bx和si、bx和di、bp和si、bp和di
错误:mov ax,[bx+bp] | mov ax,[si+di]
3。只要在[...]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中
mov ax,[bp] ax=ss*16+bp(取地址值)
◎在没有寄存器名存在的情况下,用操作符 X ptr 指明内存单元的长度,X在汇编指令中可以位word或byte:
mov word ptr ds:[0],1 | add word ptr [bx],2 | inc byte ptr ds:[2]
◎div,除法指令 div 除数
除数 8位 16位
被除数 AX DX->高16位 AX->低16位
商 AL AX
余数 AH DX
◎dd 伪指令,定义双字dword
◎dup 伪指令,用来进行数据的重复
db 3 dup (0) == db 0,0,0
db 3 dup (0,1,2) == db 0,1,2,0,1,2,0,1,2
db 3 dup ('ab','CD') == db 'abCDabCDabCD'

第九章 转移指令的原理
◎可以修改ip,或同时修改cs和ip的指令统称为转移指令
◎8086CPU的转移行为有一下几类:
只修改ip时,称为段内转移,如jmp ax
同时修改cs和ip时,称为段间转移,如jmp es:[dx]
由于转移指令对ip的修改范围不同,段内转移又分为:短转移和近转移
短转移ip的修改范围为 -128~127
近转移ip的修改范围为 -32768~32767
8086CPU的转移指令分为以下几类:
无条件转移指令(如jmp)
条件转移指令
循环指令(如loop)
过程
中断
◎offset 取得标号的偏移地址
◎jmp short 标号 实现段内短转移,对ip的修改范围为 -128~127 对应机器码中包含转移的位移 EB地址
◎jmp near ptr 标号 实现段内近转移,对ip的修改范围为 -32768~32767 对应机器码包含转移的位移
◎jmp far ptr 标号 实现段间转移 对应机器码中高地址为段地址,低地址为偏移地址 EA偏移地址段地址
◎jmp word ptr 内存单元地址(段内转移)
◎jmp dword ptr 内存单元地址(段间转移)
高地址存放目的段地址,低地址存放目的偏移地址
◎jcxz 标号 cx为0时跳转
所有有条件跳转指令都是短转移,对ip的修改范围都为 -128~127
◎loop 标号
所有循环指令都是短转移,对ip修改范围都为 -128~127
◎80×25彩色字符显示模式显示缓冲区结构:
内存地址空间中,B8000h~BFFFFFh共32KB的空间,为80×25彩色显示缓冲区。向这个地址写入数据,写入的内容将立即出现在显示器上。
在80×25彩色字符模式下,显示器可以显示25行,每行80个字符,每个字符可以有256种属性。一个字符在缓冲区占两个字节,一屏内容共占4000个字节。显示缓冲区分8页,每页4KB,显示器可以显示任意一页的内容,一般显示第0页,即B8000h~B8F9Fh。
在一行中,一个字符占两个字节的存储空间,低位字节存储字符的ASCII码,高位字节存储字符的属性,一行80字符,占160字节
属性字节的格式:
7 6 5 4 3 2 1 0
BL(闪烁) RGB(背景) I RGB(前景)
显示在 M行 N列的字符为 B800:[160*M + 2*N]

第十章 call和ret指令
◎ret用栈中数据修改ip,实现近转移
(ip) = ((ss) * 16 + (sp))
(sp) = (sp) + 2
相当于:
POP ip
◎retf用栈中数据修改cs和ip,实现远转移
(ip) = ((ss) * 16 + (sp))
(sp) = (sp) + 2
(cs) = ((ss) * 16 + (sp))
(sp) = (sp) + 2
相当于:
POP ip
POP cs
◎call指令,call指令不能实现短转移,实现转移的方法和假名牌指令原理相同
1。call 标号,段内转移
机器指令中没有转移的目的地址,而是相对于当前ip的转移位移(补码),相当于 1.push ip 2.jmp near ptr 标号
2。call far ptr 标号,段间转移
机器指令中包含转移目的地址,相当于 1.push cs 2.push ip 3.jmp far ptr 标号
3。call 16位寄存器
相当于 1.push ip 2.jmp 16位寄存器,机器指令不包含目的地址
注意:1.push ip ip先变成call后第一个字节的偏移地址,然后入栈
4。call word ptr 内存地址
相当于 1.push ip 2.jmp word ptr 内存地址
5。call dword ptr 内存地址
相当于 1.push cs 2.push ip 3.jmp dword ptr 内存地址
注意:2.push ip ip先变成call后第一个字节的偏移地址,然后入栈
◎mul 指令,乘法 a × b
a 8位 16位
b AL AX
结果 AX 高位DX,低位AX

第十一章 标志寄存器
◎ 11 10 9 8 7 6 4 2 0
OF DF IF TF SF ZF AF PF CF
◎ZF 零标志位,如果运算结果为零,则 ZF=1
◎PF 奇偶标志位,相关指令执行后,1 的个数为偶数 PF=1
◎SF 符号标志位,执行后,计算结果为负 SF=1
◎CF 进位标志位,无符号加减发生最高有效位之外的进、接位时 CF=1
◎OF 溢出标志位,有符号运算发生溢出时 CF=1
◎adc 带进位加法,adc ax,bx == (ax)=(ax)+(bx)+CF
◎sbb 带借位减法,sbb ax,bx == (ax)=(ax)-(bx)-CF
◎cmp 比较指令,相当于减法,但是不保存结果,只影响标志寄存器
cmp ax,bx
无符号比较时:
ax==bx, ZF=1
ax<>bx, ZF=0
ax< bx, CF=1
ax> bx, CF=0 and ZF=0
ax<=bx, CF=1 or ZF=1
ax>=bx, CF=0
有符号比较时(反向说明)cmp ah,bh:
SF=0 and OF=0, ah>=bh
SF=0 and OF=1, ah< bh
SF=1 and OF=0, ah< bh
SF=1 and OF=1, ah> bh
◎无符号比较跳转指令
je, ZF=1
jne, ZF=0
jb, CF=1
jnb, CF=0
ja, CF=0 and ZF=0
jna, CF=1 or ZF=1
◎DF 方向标志位,在串处理指令中,控制每次操作后si di的增减,DF=1 操作后si di递减
使用cld,std设置: cld, DF=0. std, DF=1
◎movsb 将ds:si内存单元字节送入es:di
相当于:
mov es:[di], byte ptr ds:[si] ;非8086指令
DF=0: inc si, inc di
DF=1: dec si, dec di
类似的还有movsw,传送一个字
一般使用格式为 rep movsb
相当于 s:movsb, loop s,所以要在之前设置cx
◎pushf 将标志寄存器值入栈, popf 将标志寄存器值出栈
◎标志寄存器在debug中的表示
0 OV DN NG ZR PE CY
1 NV UP PL NZ PO NC
OF DF XX SF ZF XX PF CF

第十二章 内中断
◎中断类型码:
除法错误:0
单步执行:1
int0指令:4
int n:n
◎中断向量表 0000:0000~0000:03E8,1000个单元,N号中断偏移地址为4N,段地址为4N+2,高地址为段地址,低地址为偏移地址
◎中断处理过程:
1.取得中断类型码 N
2.pushf
3.TF=0, IF=0
4.push CS
5.push IP
6.ip=4N, cs=4N+2
◎中断处理程序的编写和子程序类似,常规步骤为:
1.保存用到的寄存器
2.处理中断
3.恢复用到的寄存器
4.用iret返回(iret = pop ip, pop cs, popf)

第十三章 int指令
◎10中断
mov ah, 2 ;置光标,2号子例程为设置光标位置
mov bh, 0 ;第0页
mov dh, 5 ;行号
mov dl, 12 ;列号
int 10h
-----------
mov ah, 9 ;9号子例程为在光标位置显示字符
mov al, 'a';字符
mov bl, 7 ;颜色属性
mov bh, 0 ;第0页
mov cx, 3 ;字符重复个数
int 10h

第十四章 端口
◎端口的读写只能用in(读入)和out(写入)
◎在in和out指令中,只能使用ax或al来存放从端口中读入的数据或要发送到端口中的数据。访问8位端口时用al,访问16位端口时用dx
in al, 20h ;从20h端口读入一个字节
out 20h,al ;向20h端口写入一个字节

mov dx, 3F8h ;端口号送入dx(16位)
in al, dx ;读入一个字节
out dx, al ;写入一个字节

第十五章 外中断
◎PC机键盘处理过程
扫描码端口为60h,断码 = 通码 + 80h
键盘输入到达60h端口时,相关芯片发送9号中断,如果这时IF=1,则响应中断
◎BIOS提供int 9中断例程,用来进行基本的键盘输入处理
1.读出60h端口中的扫描码
2.如果时字符键的扫描码,将扫描码对应的ASCII码送入内存中BIOS键盘缓冲区;如果是控制键,将其转为状态字节写入0040:17单元
BIOS键盘缓冲区中,一个键盘输入用一个字单元存放,高位存放扫描码,低位存放ASCII码
状态字节含义:
0 右shift,1表按下
1 左shift,1表按下
2 ctrl,1表按下
3 alt,1表按下
4 ScrollLock,1表灯亮
5 NumLock,1表灯亮
6 CapsLock,1表输入大写字母
7 Insert,1表处于删除状态

第十六章 直接定址表
◎a db 1,2,3
以这种方式定义的标号 a 不但表示内存单元的地址,还表示内存单元的长度,即 a 处单元是一个字节单元
mov al, a[si] 相当于 mov al, cs:0[si]
mov al, a[3] 相当于 mov al, cs:0[3]
◎assume 将标号所在段和一个段寄存器联系起来,否则编译时无法确定标号的段地址
assume ds:data
data segment
a db 1,2,3
b dw 0
data ends
code段中可以使用mov al, a[si] 相当于 mov al, [si]
◎seg 取得标号的段地址
a db 1,2
b dw 0
c dd a,b ;相当于 c dw offset a, seg a, offset b, seg b
◎int 16h 读取键盘缓冲区
mov ah, 0
int 16h
◎int 13h 对磁盘进行读写
(ah)=int 13h的功能号,2-读扇区,3-写扇区
(al)=读取/写入的扇区数
(ch)=磁道号
(cl)=扇区号
(dh)=磁头号(面)
(dl)=驱动器号 0:软驱A 1:软驱B 80h:硬盘C 81h:硬盘D
es:bx 指向数据区,读入/写入的数据
返回值:(al)=读入/写入扇区数,(ah)=返回码,0表成功