汇编语言(王爽)第八章

第八章

定义描述性符号reg表示一个寄存器,sreg描述一个段寄存器

reg:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si、di

sreg:ds、ss、cs、es

8.1 bx、si、di和bp

在8086CPU中,只有这4个寄存器可以用在[……]中来进行内存单元的寻址

下面指令是错误的

mov ax,[cx]
mov ax,[ax]
mov ax,[dx]
mov ax,[ds]

在[……]中,这4个寄存器可以单个出现,或只能以4种组合出现:bxhesi、bx和di、bp和si、bp和di

如下指令也是正确的

mov ax,[bx+si+idata]
mov ax,[bp+si+idata]

如下指令是错误的

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

只要在[……]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中

mov ax,[bp]	;等价于mov ax,ss:[bp]
mov ax,[bp+si]	;等价于mov ax,ss:[bp+si]

8.2 机器指令处理的数据在什么地方

指令在执行前,所要处理的数据可以在3个地方:CPU内部、内存、端口

8.3 汇编语言中数据位置的表达

1、立即数(idata)

对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲区中),在汇编指令中直接给出

mov ax,1
add bx,2000h
mov al,'a'

2、寄存器

指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名

3、段地址(SA)和偏移地址(EA)

指令要处理的数据在内存中

8.4 寻址方式

[bx+idata]		[bx].idata		idata[bx]		[bx][idata]
[bx+si+idata]	[bx].idata[si]	idata[bx][si]

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

8086CPU的指令,可以处理两种尺寸的数据,byte和word,所以在机器指令中要指明,指令进行的是字操作还是字节操作

1、通过寄存器名指明

2、在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度。X在汇编指令中可以为word或byte

mov word ptr ds:[0],1
inc word ptr [bx]

inc byte ptr ds:[0]
add byte ptr [bx],2

在没有寄存器参与的内存单元访问指令中,用X ptr是很必要的,否则CPU无法得知所要访问的单元是字单元还是字节单元

有些命令是默认长度的,如push

8.6 寻址方式的综合应用

关于DEC公司的一条记录(1982年)如下

公司名称:DEC

总裁姓名:Ken Olsen

排名:137

收入:40

著名产品:PDP

这些数据在内存中的存储如图

汇编语言(王爽)第八章_第1张图片
到了1988年DEC公司的信息有了如下变化

1、Ken Olsen在富豪榜上的排名已升至38位

2、DEC的收入增加了70亿美元

3、该公司的著名产品已变成VAX系列

mov ax,seg
mov ds,ax
mov bx,60h

mov word ptr [bx+0ch],38
add word ptr [bx+0eh],70

mov si,0
mov byte ptr [bx+10h+si],'V'
inc si
mov byte ptr [bx+10h+si],'A'
inc si
mov byte ptr [bx+10h+si],'X'

c语言中有结构体,可以按照c语言的风格写一下这个程序

mov ax,seg
mov ds,ax
mov bx,60h

mov word ptr [bx].0ch,38
add word ptr [bx].0eh,70

mov si,0
mov byte ptr [bx].10h[si],'V'
inc si
mov byte ptr [bx].10h[si],'A'
inc si
mov byte ptr [bx].10h[si].'X'

在编程时,以结构化的角度看待所要处理的数据,bx定位整个结构体(公司)。idata定位结构体中的每一个数据区(公司的名称等),si定位数组项中的每个元素

8.7 div指令

div是除法指令,注意点

1、除数:有8位和16位两种,在一个reg或内存单元中

2、被除数:默认放在AX或者DX和AX中,如果除数为8位,被除数为16位,默认放在AX中存放,如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位

3、如果除数为8位,则AL存储除法操作的商,AH存储余数,如果除数为16位,AX存储上,DX存储余数

格式如下

div reg
div 内存单元

div byte ptr ds:[0]		; (al)=(ax)/((ds)*16+0)的商
						; (ah)=(ax)/((ds)*16+0)的余数
						
div word ptr es:[0]		; (ax)=((dx)*10000h+(ax))/((es)*16+0)的商
						; (dx)=((dx)*10000h+(ax))/((es)*16+0)的余数

实例

利用除法指令计算100001/100

100001>65535,用dx和ax联合存放,被除数是32位,所以即使除数100可以在8位寄存器中存放,但是需要用16位的寄存器保存

10001 = 186A1H,所以DX=0001H AX=86A1H

mov dx,1
mov ax,86A1H	; (dx) *10000H+(ax) = 100001
mov bx,100
div bx

执行后 (ax)=03E8H (dx)=1

利用除法指令计算1001/100

mov ax,1001
mov bl,100
div bl

8.8 伪指令dd

用dd定义双字型数据

data segement
	db 1
	dw 1
	dd 1
data ends

data:3处为00000001H

用div计算data段中第一个数据除以第二个数据后的结果,商存在第三个数据的存储单元中

data segment
	dd 100001
	dw 100
	dw 0
data ends

第一个数据为双字型,要用DX和AX联合存放

mov ax,data
mov ds,ax

mov ax,ds:[0]
mov dx,ds:[2]

div word ptr ds:[4]

mov ds:[6],ax

8.9 dup

和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 ('abc','ABC')	; 相当于db 'abcABCabcABCabcABC'

dup使用格式

db 重复次数 dup (重复的字节型数据)

dw 重复次数 dup(重复的字型数据)

dd 重复次数 dup(重复的双字型数据)

定义一共容量为200个字节的栈段

stack segment
	db 200 dup (0)
stack ends

你可能感兴趣的:(汇编)