0x01 and 和 or 指令
and 逻辑”与”运算,按位运算都一为一
例:
mov al,01100011B
and al,00111011B
执行后
al=00100011B
or 逻辑”或”运算,有一为一
例:
mov al,01100011B
or al,00111011B
执行后
al=01111011B
0x02 字符串形式
汇编中的字符串有两种字符串形式
- 用引号方式包围的字符串
例
mov al,'hello world
- 用ASCII码输入字符串
例
mov al,'61H,64H,66H'
汇编主要是用ASCII码运算字符串包括的字符串编译器会帮助计算机转换成ASCII码
[bx+idata]
[bx+idata]表示一个内存单元,他的偏移地址是:(bx)+idata(bx中的值加上idata)
例
mov ax,[bx+200]
将一个内存单元的内容写入ax,这个内存单元的长度为2个字节(字单元),存放一个字,偏移地址为bx的数值加上200,段地址在ds中
它还有以下格式
mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200
简单来说[bx+idata]就是他的偏移地址bx+idata指向的地址
[bx+idata]进行数组数据处理
例 把字符串转化大小写
假如有一个代码段
datasg segment
db 'hello'
db 'world'
datasg ends
我们可以这么获取字符串
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,5
s: mov al,[bx] ;第一个字符串
and al,11011111b
mov [bx],al
mov ah,[bx+5] ;第二个字符串
inc bx
loop s
C描述就是
char a[5]='hello';
char b[5]='world';
main()
{
int i;
i=0;
do
{
a[i]=a[i]&0xDF;
b[i]=b[i]|0x20;
i++;
}
while(i<5);
}
0x03 SI和DI
si和di是8086CPU中bx功能相近的寄存器,si和di不能分成两个8位寄存器来使用
例
mov bx,0
mov ax,[bx]
mov si,0
mov ax,[si]
mov di,0
mov ax,[do]
0x04 总结 一
常见的指向内存单元的还有
mov ax,[bx+si]
mov ax,[bx][si]
mov ax,[bx+si+idata]
常见内存地址表示格式
[idata] 用一个常量来表示地址
[bx+idata] 用一个变量+常量表示地址
[bx+si] 用两个变量表示地址
[bx+si+idata] 两个变量+一个常量表示地址
一般来说暂存的数据我们都可以在栈地址中查找
0x05 数据处理的两个基本问题
现在这里申明两个符号
reg 用来表示寄存器
ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si
sreg 用来表示段寄存器
ds,ss,cs,es
1.处理的数据在什么地方?
- 机器指令处理的数据在何方
绝大部分机器指令都是进行数据处理的指令,大致分为读取,写入,运算。
在指令层面并不会关心数据的值是多少,而关心它执行前的位置
所要处理的数据在三个地方:CPU内部,内存,端口
机器码 | 汇编指令 | 指令执行前数据的位置 |
---|---|---|
8E1E0000 | mov bx[0] | 内存, ds:0单元 |
90C3 | mov bx,ax | CPU内部, ax寄存器 |
BB0100 | mov bx,1 | CPU内部,指令缓冲器 |
- 汇编中数据地址的表达方式
- 立即数
- 寄存器
- 段地址:偏移地址
- 寻址方式
2.要处理的数据有多长?
8086CPU的指令,可以处理两种尺寸的数据,byte和word.所以在机器指令中要指明,指令进行的是字操作还是字节操作。
汇编用一下方法处理
1)通过寄存器名指明要处理的数据的尺寸
例如寄存器中的al和ax
通过ax操作的都是字
通过al操作的都是字节
2)在没有寄存器的情况下,用操作符X ptr指明内存单元的长度,X在汇编中的指令可以为word或Byte
例如
下面的指令中,用word ptr指明了访问的内存单元是一个字单元
mov word ptr ds:[0],1
下面的指令中,用byte ptr指明了访问的内存单元是一个字单元
mov byte ptr ds:[0],1
在没有寄存器参与的内存单元访问指令中,用word ptr或byte ptr显性的指明所要访问的内存单元的长度是很有必要的,否者CPU无法得知要访问的单元是字还是字节单元
在修改的时候就会很明显的
mov ax,2000H
mov ds,ax
mov byte ptr [1000H],1
他就将内存的内容变为
2000:1000 01 FF FF FF FF
mov ax,2000H
mov ds,ax
mov word ptr [1000H],1
2000:1000 01 00 FF FF FF
0x06 div
div 是触发指令,使用div做除法的时候应注意
- 除数:有8位和16位两种,在一个reg或内存单元中
- 被除数:默认放在AX或DX中如果是8为被除数就是16位默认在AX中存放,如果是除数是16位,被除数则为32位,默认在DX和AX两个中存放,DX存放高16位,AX存放低16位
- 结果:如果除数为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 [bx+si+8]
div byte ptr [bx+si+8]
div word ptr es:[0]
0x07 伪指令dd
db和dw是用于定义字节型和字形数据
dd是用来定义dword 双字型数据的例如
data segment
db 1
dw 1
dd 1
data ends
在data段定义了3个数据:
第一个数据为01H,在data:0处,占1个字节
第二个数据为0001H,在dat:1处,占一个字
第三个数据为00000001H,在data:3,占2个字
0x08 dup
dup它是和db,dw,dd等数据定义伪指令配合使用的,用来进行数据的重复
例
db 3 dup (0)
db 3 dup(0,1,2)
定义了3个字节,它们的值都是0 相当于 db 0,0,0
定义了9个字节,他们是0,1,2,0,1,2,0,1,2