《汇编语言》(第2版)学习笔记

第1章 基础知识

1.15 内存地址空间

8086CPU内存地址分配
《汇编语言》(第2版)学习笔记_第1张图片

第2章 寄存器

实验1 查看CPU和内存 Debug的使用

常用的几个命令

《汇编语言》(第2版)学习笔记_第2张图片
按Alt+Enter可进入\退出全屏模式

用e命令向内存中写入字符或字符串

e 1000:0  '1' 'a' 'b' 'c'    *//写入字符*
e 1000:0 "abcde"  2 'x' "1+2+3=?"   *//写入字符串*

第3章 寄存器(内存访问)

3.1内存中字的存储

N地址单元存放的字节型数据
N地址字单元存放的字型数据——N地址为起始

3.2 DS和[address]读写内存的方法

8086CPU以 段地址:偏移地址的形式操作内存单元
程序中默认在DS寄存器中存放段地址
程序中以[address]的形式表示偏移地址
8086CPU中不允许直接改变段地址寄存器的值

例如:读取100066H地址单元的字节

mov ax,1000
mov ds,ax
mov bl,[66]  //解释:mov bl,1000:66

3.7 CPU提供的栈机制

SS和SP分别存放栈的段地址和偏移地址
8086CPU入栈和出栈都是以字为单位操作的
入栈时,栈指针由高地址向低地址移动
出栈时,栈指针由低地址向高地址移动
栈的大小:为16的倍数

3.9 push和pop指令

支持三种形式
push/pop 寄存器/段地址寄存器/内存单元

mov ax,1000
mov ds,ax
push [0]   //mov ss:sp 1000:0

push指令的执行步骤:1)sp -= 2; 2)将ss:sp中的字型数据取出
pop指令的执行步骤: 1)将ss:sp中的字型数据取出;2)sp += 2

实验2

注意:Debug中用t命令执行指令时,若修改段地址寄存器SS,则下一条语句会被自动执行。

第4章 第一个程序

4.2 源程序

asume cs:code
code segment
	mov ax,0123h
	mov bx,0456h
	add ax,bx
	add ax,ax

	mov ax,4c00h
	int 21h
code ends
end

汇编语言的源程序包含两种指令:
1)伪指令——编译器执行
a)定义程序段
xxxx segment

xxxx ends
b)结束编译:end
c)关联段地址寄存器:asume
asume cs:code,ds:data,ss:stack

2)汇编指令——CPU执行
程序返回指令:
mov ax,4c00h
int 21h

4.9 程序执行过程的跟踪

执行程序载入之后:
1)CX寄存器中存放的值表示程序的大小
2)CS:IP存放程序执行地址
3)DS寄存器存放PSP的地址,PSP区大小为256个字节,PSP之后紧跟代码区
即 CS:IP = DS + 10h

第5章 [bx]和loop

5.1 [bx]

[bx]表示一个地址单元,偏移放在bx寄存器中

 mov ax,[bx] //(ax) = ((ds)*16+(bx))

5.2 loop和cx

计算 2^10

     mov ax,2
     mov cx,9
lp: add ax,ax
     loop lp

5.3 debug中p命令和g命令

p:可以执行到循环结束
g 偏移地址:相当于断点执行到ds:偏移地址的地方

5.4 debug和编译器masm对指令的不同处理

debug中:mov ax,[0] 相当于 mov ax,ds:0
masm编译:mov ax,[0] 相当与 mov ax,0
访问ds:0处的内存单元应写成:

mov bx,0
mov ax,[bx]

或者

mov ax,ds:[0]

5.6 段前缀

mov ax,20h
mov es,ax
mov es:[0h],ax

出现在访问内存单元的指令中,用于显示的表示内存单元段地址的“ds”,“cs”,“ss”,“es”,在汇编语言中称之为段前缀。

第6章 包含多个段的程序

6.1在代码段中使用数据

1)dw 0123h,0456h,0789h
dw(define word)的含义是定义字型数据
db(define byte)的含义时定义字节型数据
2)代码结束时end后面加标号,则指明代码入口

assume cs:code
code segment
	....
	数据
	....
start:  ....
	....
code ends
end start   //指明代码入口在start处  	

第7章 更灵活的定位内存地址的方法

7.1 and和or指令

1)and指令:按位与指令——将相应位置零

mov al,01000011B
and al,01110001B

执行后:al=01000001B
2)or指令:按位或指令——将相应位置一

mov al,01000011B
or al,01110001B

执行后:al=01110011B

7.5 [bx+idata]

[bx+idata]表示一个地址单元,地址单元的段地址放在ds中,偏移地址为(bx)+idata。
[bx+idata]还常表示为:idata[bx]或[bx].idata

mov ax,[bx+200]
mov ax,200[bx]
mov ax,[bx].200

都表示读取(ds)*16+(bx)+200地址字单元的内容到寄存器ax中

7.7 SI和DI

si和di是8086CPU中功能和bx相近的两个寄存器,si和di不能分成两个8位寄存器来使用

mov ax,[bx]
mov ax,[si]
mov ax,[di]

7.8 [bx+si]和[bx+di]

mov ax,[bx+si]也可以表示为:mov ax,[bx][si]
mov ax,[bx+di]也可以表示为:mov ax,[bx][di]

7.9 [bx+si+idata]和[bx+di+idata]

[bx+si+idata]和[bx+di+idata]用法相同

mov ax,[bx+si+200]
mov ax,[200+bx+si]
mov ax,200[bx][si]
mov ax,[bx].200[si]
mov ax,[bx][si].200

以上语句表示同一个意思

第8章 数据处理的两个基本问题

1)处理的数据放在什么地方
2)要处理的数据有多长

8.1 bx,si,di和bp

1)在8086CPU中只有这4个寄存器可以放在[…]中进行内存的寻址
2)在[…]中这4个寄存器可以单独出现,或只能以4种组合方式出现:[bx+si],[bx+di],[bp+si],[bp+di]。
3)只要在[…]中出现bp,而没有显示的给出段地址,则默认段地址存放在ss中。其它默认在ds中。

8.2数据在什么地方

在指令执行前,要处理的数据可以在3个地方:
1)CPU内部
2)内存
3)端口
《汇编语言》(第2版)学习笔记_第3张图片

8.3数据位置的表达

1)立即数
2)寄存器
3)段地址+地址偏移

8.5 指令要处理的数据有多长

1)通过寄存器名指明要处理的数据的长度
a)字操作
mov ax,ds:[0]
b)字节操作
mov al,ds:[0]
2)用操作符word ptr或byte ptr 显式的指明要操作的数据长度
a)字操作

mov word ptr ds:[0],1
inc word ptr ds:[0]
add word ptr ds:[2],2

b)字节操作

mov byte ptr ds:[0],1
inc byte ptr ds:[0]
add byte ptr ds:[2],2

8.7 div指令

格式:
1)div 寄存器
2)div 内存单元
概念:
1)除数有8位和16位两种,对应被除数有16位和32位两种
2)如果除数为8位,则被除数为16位,位于ax中
3)如果除数位16位,则被除数位32位,低16位在ax中,高16位在dx中
4)如果除数为8位,则商在al中,余数在ah中
5)如果除数位16位,则商在ax中,余数在dx中
例子:

div byte ptr ds:[0]
// al = ax / (ds:[0])
// ah = ax % (ds:[0])

div word ptr ds:[0]
// ax = ((dx<<16)+ax) / (ds:[0])
// dx = ((dx<<16)+ax) % (ds:[0])

div bl
// al = ax / bl
// ah = ax % bl

div bx
// ax = ((dx*10000h) + ax) / bx
// dx = ((dx*10000h) + ax) % bx

8.8伪指令dd

dd定义双字类型数据,占32位

8.9 dup

dup和db,dw,dd等数据定义伪指令一起配合使用,用来进行数据的重复。
格式:db/dw/dd 重复的个数 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’,‘AB’) //db ‘abABabABabAB’

第9章 指令转移的原理

1)修改IP或同时修改CS:IP的指令统称为转移指令
2)转移行为分类
a)段内转移,只修改IP:jmp ax
a.1)短转移:IP的修改范围:-128~127
a.2)近转移:IP的修改范围:-32768~32767
b)段间转移,同时修改CS:IP:jmp 1000:0
3)8086CPU转移指令分类
a)无条件转移(如jmp)
b)条件转移
c)循环指令(如loop)
d)过程
e)中断

9.1 操作符offset

offset的功能是取得标号的偏移地址

code segment
start: mov ax,offset start   ;相当于mov ax 0
s:     mov ax,offset s       ;相当于mov ax 3
code ends

9.3 jmp short 标号

实现段内转移,将程序转到标号处执行指令,对IP的修改范围为-128~127
jmp short 标号的含义:IP = IP + 8位位移
1)8位位移 = 标号处的地址 - jmp指令后第一个字节的地址
2)short指出位移为8位,范围为-128~127
3)8位位移有编译器在编译时算出
jmp near ptr 标号:IP = IP + 16位位移

assume cs:code
code segment
start:		mov ax,0
		jmp short s
		add ax,1
s:		inc ax
code end
end start

9.4 jmp far ptr 标号

段间转移,指明用标号的段地址和偏移修改CS和IP

9.5 jmp 16位寄存器

IP = 16位reg

9.6 jmp 内存单元

1)jmp word ptr 内存单元 (段内转移)
2)jmp dword ptr 内存的那元 (段间转移)
CS = 高字,IP = 低字

9.7 jcxz指令

jcxz位有条件转移指令,所有的有条件转移都是短转移,在对应机器码中包含的是转移位移,而不是目标地址。对IP修改范围为:-128~127。
格式:jcxz 标号
解释:如果(CX) = 0,则转移到标号处执行

9.10 编译器对转移位移超界的检测

实验9 屏幕显示

8086CPU中,内存B8000H~B8FFFH共32KB,为80x25(行x列)彩色字符模式的显示缓冲区。在80x25彩色字符模式下,可以显示25行,每行80个字符,每个字符2个字节,低字节存放ASCII码,高字节存放属性,属性定义如下:
《汇编语言》(第2版)学习笔记_第4张图片
显示缓冲区分为8页,每页4KB(约4000个字节),显示器可以显示任意一页的内容,通常情况显示第0页的内容,即B8000H~B8F9FH的4000个字节会显示在屏幕上。第1页缓冲区中:
000~09F对应显示器上的第1行
0A0~13F对应显示器上的第2行
140~1DF对应显示器上的第3行

F00~F9F对应显示器上的第25行
以下代码在屏幕中央显示绿底红字:

assume cs:code,ds:data

data segment
	db 'welcome to masm!'
data ends

code segment
start:	mov ax,data	
	mov ds,ax
	mov ax,0b800h	;显示段地址
	mov es,ax
	mov bx,780h	;中间行
	mov si,0		;列数
	mov cx,16 	;循环次数

s:	mov al,[si]		;字符
	mov ah,24h	;字符属性
	mov dx,si
	add si,si
	mov es:[bx].72[si],ax
	mov si,dx
	inc si
	loop s

	mov ax,4c00h
	int 21h
code ends
end start

第10章 call 和 ret指令

10.1 ret 和 retf

ret用栈中的数据修改IP的内容,相当于:

pop ip

retf用栈中的数据修改IP和CS的内容,相当于:

pop ip
pop cs

10.2 call指令

call指令执行时,进行两步操作:
1)将IP或CS和IP压栈
2)转移

10.3 依据位移转移的call指令

格式:
call 标号
解释:
1)push ip
2)jmp near ptr 标号

10.4 依据目的地址转移的call指令

格式:
call far ptr 标号
解释:
push cs
push ip
jmp far ptr 标号

10.5 依据寄存器转移的call指令

格式:
call 16为寄存器
解释:
push ip
jmp 16为寄存器

10.6 依据内存转移的call指令

1)call word ptr 内存单元
解释:
push ip
jmp word ptr 内存单元
2)call dword ptr 内存单元
push cs
push ip
jmp dword ptr 内存单元

10.7 call 和 ret 配合使用

10.8 mul指令

mul即乘法指令
注意:相乘的两个数,要么都是8位,要么都是16位
格式:
1)mul 寄存器
2)mul byte/word ptr 内存地址
解释:
8位相乘:一个乘数在al中,结果在ax中
16位相乘:一个乘数在ax中,结果高16位在dx中,低16位在ax中

10.12 寄存器冲突的问题

编写子程序的标准框架:
子程序入口:子程序中要用的寄存器入栈
子程序内容
子程序中的寄存器出栈
返回(ret/retf)

第11章 标识寄存器

8086CPU标识寄存器共使用9位标识位
《汇编语言》(第2版)学习笔记_第5张图片
标志寄存器中存储的信息常称为程序状态字(PSW)

11.1 ZF标志——0标志位

第6位。相关指令执行后,结果为0,zf=1;结果为1,zf=0

11.2 PF标志——奇偶校验标志位

第2位。相关指令执行后,结果中1的个数为偶数,PF=1;1的个数为技术,PF=0。

11.3 SF标志——负数标志位

第7位。相关指令执行后,结果为负数,SF=1;否则,SF=0

11.4 CF标志——进位标志位

第0位。在进行无符号数运算时,记录了最高有效位向更高位的进位(加法时)或借位(减法时)结果

11.5 OF标志——溢出标志位

第11位。对有符号数的运算而言

11.6 adc指令

带进位加法指令,利用CF位。

11.7 sbb指令

带节为减法指令,利用CF位。
sbb ax,bx ;(ax) = (ax) - (bx) - CF

11.8 cmp指令

比较指令。操作数1-操作数二,不保存结果,只影响标志位。
格式:cmp 操作数1,操作数2

11.9 检测标志位的条件转移指令

常结合cmp指令一起使用。分为两种
1)无符号数的比较结果
《汇编语言》(第2版)学习笔记_第6张图片
b——below,a——above
2)有符号数的比较结果

11.10 DF标志和串传送指令

1)DF标志位的修改

cld   //DF = 0  在串传送指令中si和di递增
std  //DF = 1   在串传送指令中si和di递减

2)串传送指令

rep movsb  //传送字节
//((es)*16+di) = ((ds)*16+si)
//inc di   //DF=0
//inc si//dec di  //DF=1 
//dec si
rep movsw //传送字,原理和 movsb一样

3)实例

mov ax,dstdata
mov es,ax
mov di,0	//目的数据地址
mov ax,srcdata
mov ds,ax
mov si,0  //源数据数据地址
cld   //DF=0,si和di递增
mov cx,8  //传送8个数据
rep movsb

11.11 pushf指令和popf指令

标志寄存器压栈和出栈

11.12 标志寄存器在debug中的表示

《汇编语言》(第2版)学习笔记_第7张图片

实验11 实现程序

编程实现把以0结尾的字符串中的小写字母全部转换为大写,其余字符不变。程序如下:

;功能:将以0结尾的字符串中的小写字符变为大写字母
;参数:ds:si指向字符串的首地址
letterc:
	push si
	;以上位寄存器保护过程
beg:	
	cmp byte ptr [si],0
	je finish
	cmp byte ptr [si],'a'
	jb next			;小于a则进入下一轮判断
	cmp byte ptr [si],'z'
	ja next			;大于z则进入下一轮判断
	and byte ptr [si],11011111B	;小写转换为大写
next:	
	inc si
	jmp short beg
	;以下位寄存器恢复过程
finish:	
	pop si
ret	

第12章 内中断

12.1内中断的产生

8086CPU内部发生四种情况,将产生内中断
序号, , 事件, 中断类型码, 备注
1, , 除法错误 , , 0 , ,,比如div溢出
2, , 单步执行 , , 1
3, , 执行into指令, 4,
4, , 执行int指令, ,,,,, int n

12.3中断向量表

8086CPU中断向量表指定放在0地址处,在0000:0000~0000:03ff的1024个单元中存放中断向量表。
一个表项占两个字,即4个字节;高地址存放中断服务程序的段地址,低地址存放中断服务程序地址的偏移地址。

12.4中断过程

8086CPU在收到中断信息后,发生如下过程
《汇编语言》(第2版)学习笔记_第8张图片

12.5 中断处理程序和iret指令

中断处理程序的一般过程如下
《汇编语言》(第2版)学习笔记_第9张图片

第13章 int指令

13.1 int指令

一般情况,系统把具有一定功能的程序作为中断处理程序共给应用程序调用,编程时可通过int指令调用这些程序。

13.6 BIOS中断例程应用

1)设置光标
《汇编语言》(第2版)学习笔记_第10张图片
2)在光标处显示字符
《汇编语言》(第2版)学习笔记_第11张图片

13.7 DOS中断例程应用

mov ax,data
mov ds,ax
mov dx,0	;ds:dx为显示字符的首地址
mov ah,9
int 21h
		
mov ax,4c00h
int 21h

实验13

以下程序在屏幕2,4,6,8行显示四行诗句

assume cs:code
data segment
	db 'welcome to masm!','$'
data ends
code segment 
	s1:
		db 'Good,better,best,','$'
	s2:
		db 'Never let it rest','$'
	s3:
		db 'Till good is better','$'
	s4:
		db 'And better ,best.','$'
	s:
		dw offset s1,offset s2,offset s3,offset s4
	row:
		db 2,4,6,8
	main:
		mov ax,cs
		mov ds,ax
		mov si,offset s 	;显示的行
		mov di,offset row
		mov cx,4
	next:
		mov bh,0
		mov dh,[di]
		mov dl,36
		mov ah,2
		int 10h		;置光标
		
		mov dx,[si]
		mov ah,9
		int 21h
		add si,2
		inc di
		loop next
		
		mov bh,0
		mov dh,24
		mov dl,0
		mov ah,2
		int 10h
		
		mov ax,4c00h
		int 21h	
code ends
end main

第14章 端口

14.1 端口的读写

在PC机系统中,CPU最多可以定位64KB个端口,端口号为0~65535。
端口的读写指令:in和out
注意:in和out指令中只能用ax和al来进行数据的读写

in al,30h
out 30h,al

14.2 COMS RAM 芯片

1)包含一个实时钟和一个有128单元的ram存储器
2)该芯片有电池供电。关机后实时钟仍正常工作,ram中信息 不丢失
3)128字节的ram中,实时钟占用0~0dh单元来保存时间信息。
4)芯片内部有两个端口70h和71h
5)70h为地址端口,存放访问的cmos ram单元的地址;71为数据端口,存放读写的数据。对CMOS RAM的读写分为两步:
a)将地址送入端口70h:out 70h,al
b)从端口71h读写数据:in al,71h

14.3 shl和shr指令

shl是逻辑左移指令,它的功能是:
1)把数据向左移动
2)把最后移出的一位放入CF钟
3)最低位用0补充

mov al,01000000b
shl al,1

执行后:(al)=10000000b,(CF)=0
注意:如果移动的位数大于1,则必须放在cl中,如:

mov cl,3
mov al,10100001b
shl al,cl

执行后:(al)=00001000b,(CF)=1

shr是逻辑右移指令,原理和shl一样

14.4 CMOS RAM中存储的时间信息

《汇编语言》(第2版)学习笔记_第12张图片

第15章 外中断

15.1接口芯片和端口

CPU通过端口和外部设备进行联系。

15.2 外中断信息

在PC系统中,外中断源一共有两类:
1)可屏蔽中断
IF=1,响应中断;IF=0,不响应中断。
sti:设置IF=1
cli:设置IF=0
2)不可屏蔽中断
不可屏蔽中断的中断类型码固定为2。
几乎所有由外设引起的中断,都是可屏蔽中断。

15.3 PC机键盘的处理过程

键盘上部分按键的扫描码(通码):
《汇编语言》(第2版)学习笔记_第13张图片《汇编语言》(第2版)学习笔记_第14张图片
断码 = 通码+80H
键盘按下按键时,将响应按键的通码送到端口寄存器60h。
字符键:送入内存的BIOS键盘缓冲区,共15个字节
控制键:送入0040:17地址单元,含义如下:
《汇编语言》(第2版)学习笔记_第15张图片

15.4 编写int9中断例程

你可能感兴趣的:(汇编,8086cpu,16位汇编)