数据处理的两个基本问题
数据处理时所有CPU都要面临两个基本问题:
1、要处理的数据在什么地方?
2、要处理的数据有多长?
我们可以定义两个描述性符号reg和sreg,reg代表一个寄存器,sreg代表一个段寄存器。
reg的集合包括:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si和di
sreg的集合包括:ds、ss、cs、es
bx、si、di和bp
在8086CPU中,只有这4个寄存器能直接放入括号中表示内存单元的偏移地址,其他普通的寄存器是不能放入括号中的。括号中也可以放入2个寄存器,但是不是所有组合都能放入括号中,只能以4种组合出现:bx和si、bx和di、bp和si、bp和di,当然这4种组合都能加上idata。
前三种寄存器我们都有接触,bp寄存器是比较特别的,只要在括号中使用bp寄存器,而指令中又没有显性的给出段地址,段地址就默认在ss寄存器中。(其他情况下段地址都是在ds中)
要处理的数据位置
机器指令要处理的数据大概分为三种:
1、立即数idata,它是直接包含在机器指令中的数据,执行前该数据在CPU的指令缓冲器中。
2、寄存器:指令要处理的数据在寄存器中,在汇编语言中要给出寄存器名。
3、内存地址:用中括号表示数据在某个内存地址中。
寻址方式小结
定位内存单元的方法被称为寻址方式,总结如下:
要处理的数据长度
在8086CPU中,可以处理两种尺寸的数据,byte和word,一般要在指令中指明进行的是字操作还是字节操作。汇编语言在处理这个问题时有以下几种解决方案:
1、通过寄存器名指定要处理的数据尺寸:如果是ax、bx、ds等寄存器就说明操作的是字,如果是al、bl等寄存器说明操作的是字节。
2、如果指令不涉及寄存器名,而是只涉及内存地址和立即数,此时应该在指令后加入word ptr或byte ptr来表明访问的是一个字节还是一个字:
mov word ptr ds:[0],1
inc word ptr [bx]
mov byte ptr ds:[0],1
inc byte ptr [bx]
3、有些指令对于访问的是字单元还是字节单元有默认设置,如push就只进行字操作。
除法指令div
div使用时的基本格式:
div reg或内存单元
使用div时只需要指定除数即可,除数有8位和16位两种。如果除数为8位,则被除数为16位,默认在AX中存放;如果除数为16位,则被除数为32位,在DX(高16位)和AX(低16位)中存放。
如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。这就意味着一个div指令影响两个寄存器的值。
如果要利用除法做100001/100,首先被除数100001大于65535,所以必须令被除数为32位,除数则应该为16位,100001的16进制形式为186A1H,计算方法如下:
mov dx,1
mov ax,86A1H
mov bx,100
div bx
定义数据指令
之前我们用db和dw定义字节型数据和字型数据,还有一个指令dd,它的意思是define double word,它用来定义双字型数据,一次定义4个字节,这几个指令都是编译器需要识别处理的伪指令。
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\'