您的位置:首页 > 其它

汇编学习笔记--数据处理的两个基本问题

2013-04-15 21:15 274 查看
一、bx、si、di、bp

在8086CPU中,只有bx、si、di、bp这四个寄存器可以通过[……]方式来进行内存单元的寻址;

这四个寄存器可以单独存在,也可以以组合的形式进行寻址,但是bx和bp不能一起使用,si和di不能一起使用,所以即使组合最多也只能两个组合,不会有三个组合在一起的形式,当然可以加个常量:[bx+si+idata];

只要使用bp,而段地址没有显式给出,则默认段地址为ss,而其它三个的默认段地址均为ds。注意是只要使用bp,若bp和si都存在,此时si默认段地址是ds,但是因为bp的存在,这个寻址的段地址仍为ss。

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

一共有三个地方:内存、寄存器、指令缓冲器

mov ax,[0]     mov ax,bx    mov ax,1

像1这种直接包含在机器指令中的数据成为立即数,执行该指令时它在CPU的指令缓冲区中。

三、寻址方式

1.直接寻址:[2]

2.寄存器间接寻址:[bx]

3.寄存器相对寻址:[si+idata]

4.基址变址寻址:[bp+di]

5.相对基址变址寻址[bp+si+idata]

四、指令要处理的数据有多长

1.通过寄存器名指明要处理的数据长度

2.在没有寄存器名时,可通过word ptr和byte ptr指明内存的长度为字或字节

mov word ptr ds:[0],1

inc byte ptr [bx]

五、div指令

算数表达式:A/B     汇编指令表示:div  B

那么A是谁?depengs on B

case B为字节:A=DX AX,即A为32位,DX在高位,AX在低位         计算的结果包括两部分:商在AX中,余数在DX中

case B为字:A=AX,即A为16位    计算的结果也包括两部分:商在AL中,余数在AH中

实例:利用除法计算100001/100

 

mov ax,86a1h
mov dx,1
mov bx,100
div bx


六、伪指令dd和操作符dup

db-- 字节型数据

dw-字型数据

dd-双字型数据

db 3 dup(0)相当于db 0,0,0,

db 2 dup (0,1,2)相当于db 0,1,2,0,1,2

db 2 dup(‘abc’,‘ABC’)相当于db ‘abcABCabcABC’

 

七、实例

题目:《汇编语言》第2版 王爽 第8章实验7

 

assume cs:code,ds:data,ds:table,ss:stack
;?????这里的cs,ds有什么用?可以重复使用吗?

data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985'
db '1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
;以上是表示21年的21个字符串

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3573000,4649000,5937000
;以上是21年的公司总收入

dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;以上是21年公司雇员人数

data ends

table segment

db 21 dup('year summ mm ?? ')   ;这里需要21行,没行都占用16个字节

table ends

stack segment

db 16 dup(0)

stack ends

code segment
start:  mov ax,data
mov ds,ax    ;将data数据段段地址赋给段寄存器ds

mov ax,table
mov es,ax    ;将table数据段段地址赋给段寄存器es

mov ax,stack
mov ss,ax
mov sp,10h   ;初始化栈的段地址和栈顶

;开始复制表示年的字符串

mov cx,21  ;外层循环次数为21
mov si,0   ;ds:[si]来表示data段数据,从[0]开始
mov bx,0   ;es:[bx][di]来表示table段数据,bx=bx+16,di=di+1  di从0到3

s0:     push cx    ;通过栈保存外层计数器cx
mov cx,4   ;内层循环次数为4
mov di,0   ;di需要每次都需置零

s1:     mov al,[si]         ;从data段按字节读取数据
mov es:[bx][di],al  ;将数据从data段复制到table段,按字节复制
inc di              ;talbe段读取下一个字节
inc si              ;data段读取下一个字节
loop s1

pop cx      ;恢复外层循环次数
add bx,16
loop s0

;结束复制表示年的字符串

;开始复制公司总收入

mov cx,21  ;外层循环次数为21
;mov si,0   ;ds:[si]来表示data段数据
mov bx,5   ;es:[bx][di]来表示table段数据,bx=bx+16,di=di+1  di从0到3

s2:     push cx    ;通过栈保存外层计数器cx
mov cx,2   ;内层循环次数为4
mov di,0   ;di需要每次都需置零

s3:     mov ax,[si]         ;从data段按字节读取数据
mov es:[bx][di],ax  ;将数据从data段复制到table段,按字节复制
add di,2              ;talbe段读取下一个字节
add si,2              ;data段读取下一个字节
loop s3

pop cx      ;恢复外层循环次数
add bx,16
loop s2

;结束复制公司总收入

;开始复制雇员人数

mov cx,21  ;外层循环次数为21
mov bx,10   ;es:[bx][di]来表示table段数据,bx=bx+16,di=di+1  di从0到3
s4:     mov ax,[si]
mov es:[bx],ax
add si,2
add bx,16
loop s4

;结束复制雇员人数

;开始计算人均收入

;被除数:es:[bx+5]--[bx+8]
;除数:es:[bx+10]--[bx+11]
;商:es:[bx+13]--[bx+14]
;bx=0,bx=bx+16
mov cx,21  ;外层循环次数为21
mov bx,0
s5:     mov ax,es:[bx+5]
mov dx,es:[bx+7]
div word ptr es:[bx+10]
mov es:[bx+13],ax
add bx,16
loop s5

;结束计算人均收入

;要复制dd型数据,也就是4个字节,可以按字复制,也可以按字节复制,这里采用按字复制

mov ax,4c00h
int 21h
code ends

end start
;copy form ds:[bp][si] to es:[bx][di]
;for year: si between 0 and 3,di between 0 and 3,bp = bp + 4,
;for destination: bx=bx+16, di from 0 to 3, from 5 to 8, from 10 to 11. from 13 to 14
;for source:
;0--3, 84--87, 168--169
;4--7, 88--91, 170--171
;4*i+0:4*i+3,
;4*i+84,i*4+87
;2*i+168,2*i+169


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: