您的位置:首页 > 其它

汇编语言:第八章 数据处理的两个基本问题

2015-07-13 18:36 288 查看
本章是前面章节的总结

1.处理的数据在哪?

2.数据有多长?

以下理由reg表示寄存器,sreg表示段寄存器

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

sreg有:cs,ds,es,ss

8.1 bx,si,di 和 bp

1) [..]中只能使用这4种寄存器,其他的不可以

2) 只能有下列使用组合,其他的不可以

  [bx],[bp],[si],[di],[bx+si],[bx+di],[bp+si],[bp+di] 可以+idata

3) 只要[...]中有bp,并且没给出段地址,段地址就在ss中

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

可以在1)CPU中 2)内存中 3)端口中

实例:

mov ax,bx   数据bx在CPU中

mov bx,[0]  数据在内存中

mob ax,0   数据在CPU内部指令缓冲器

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

1)立即数:指令缓冲器

2)寄存器:CPU寄存器中

3)段地址SA+偏移地址EA:内存中, [bx]默认ds段寄存器,带bp的就是ss段寄存器,还可以手动指定 cs: ds: ss: es:

8.4 寻址方式



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

1)寄存器操作由寄存器类型决定数据长度

  mov ax,1  长度2字节

  mov al,1  长度1字节

2)没有寄存器的指令 利用 ptr 指定长度

  mov byte ptr ds:[bx],1 把1当做单字节放入ds:bx中

  mov word ptr ds:[bx],1 把1当做一个字放入ds:bx和ds:bx+1中

3)其他的

  push [0] pop [0] 栈操作都是按照字为单元的

8.6寻址方式的综合应用

实例:某公司82年信息如下名称:DEC 总裁:Ken Olsen 排名:137 收入:40 著名产品:PDP

这些数据在内存中位置如图所示 (从seg数据段的偏移地址60开始存放)



问题:88年公司的排名升至38,收入增加70,著名产品变为VAX 则如何改内存?

汇编                            C

mov ax,seg                     struct company{char cn[3]; char hn[9]; int pm;

mov ds,ax                       int sr;char cp[3]}

mov bx,60H                struct company dec={"DEC","Ken Olsen",137,40,"PDP"}

mov word ptr [bx].0CH,38          dec.pm = 38;

add word ptr [bx].0EH,70           dec.sr = dec.sr + 70

mov si,0                   int i; i=0;

mov byte ptr [bx].10H[si],'V'         dec.cp[i]='V';

inc si                      i++;

mov byte ptr [bx].10H[si],'A'        dec.cp[i]='A'

inc si                      i++;

mov byte ptr [bx].10H[si],'X'        dec.cp[i]='X'

总结:利用[bx].idata修改结构体中的一般变量

   利用[bx].idata[si]修改结构体中的数组变量

8.7 DIV指令

除数有8位和16位,对应被除数16位和32位;

除数由寄存器(bl8,bx16)或者内存地址(单字节8,字单元16)给出,被除数由ax(16)或者((dx)*10000H+(ax))(32)给出;

8位除数时,AH存余数,AL存商。16位除数时,DX存余数,AX存商;

当除数是由内存地址给出时需要指定是byte还是word ptr

实例一:计算100001/100

易知:

除数100放在8位和16位寄存器/内存地址中都可以的;

被除数100001变成16进制=186A1H 一个AX不够存,所以DX放1,AX放86A1H;

DIV操作之后余数应该在DX中,商应该在AX中;

mov dx,1

mov ax,86A1H

mov bx,100

div bx

实例二:计算1001/100

易知:

除数100放在8位和16位寄存器/内存地址中都可以的;

被除数1001是可以放在16位中的,所以放在AX中;

DIV操作之后余数应该在AH中,商应该在AL中;

mov ax,1001

mob bl,100

div bl

8.8 伪指令dd

db,dw定义单字节1和字单元2,dd定义双字单元4

实例:计算第一个数除以第二个数,商放在第三个数中

assume cs:code,ds:data

data segment
dd 100001
dw 100
dw 1
data ends

code segment
start:
mov ax,data
mov ds,ax    
mov dx,ds:[2]       //100001高位放在dx中
mov ax,ds:[0]       //100001低位放在dx中
div word ptr ds:[4]
mov ds:[6],ax

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

8.9 dup操作符

dup和db,dw,dd一样都是由编译器识别的,dup配合这三种伪指令使用,用于复制数据

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

  db 3 dup (0)       =>     db 0,0,0

  db 3 dup (1,2)      =>     db 1,2,1,2,1,2

  db 3 dup ('ab','AB')   =>     db 'abABabABabAB'

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

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

dup是非常有用的操作符,比如 定义N个字节的栈段就可以:

stack segment

db N dup (0)

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