汇编基础知识五

0x01 and 和 or 指令

and 逻辑"与"运算,按位运算都一为一

例:

mov al,01100011B
and al,00111011B
执行后
al=00100011B

or 逻辑"或"运算,有一为一

例:

mov al,01100011B
or al,00111011B
执行后
al=01111011B

0x02 字符串形式

汇编中的字符串有两种字符串形式

  1. 用引号方式包围的字符串

    mov al,'hello world
  2. 用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 数据处理的两个基本问题

现在这里申明两个符号

  1. reg 用来表示寄存器

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

  2. sreg 用来表示段寄存器

    ds,ss,cs,es

1.处理的数据在什么地方?

  • 机器指令处理的数据在何方

绝大部分机器指令都是进行数据处理的指令,大致分为读取,写入,运算。

在指令层面并不会关心数据的值是多少,而关心它执行前的位置

所要处理的数据在三个地方:CPU内部,内存,端口

机器码 汇编指令 指令执行前数据的位置
8E1E0000 mov bx[0] 内存, ds:0单元
90C3 mov bx,ax CPU内部, ax寄存器
BB0100 mov bx,1 CPU内部,指令缓冲器
  • 汇编中数据地址的表达方式
  1. 立即数
  2. 寄存器
  3. 段地址:偏移地址
  • 寻址方式

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做除法的时候应注意

  1. 除数:有8位和16位两种,在一个reg或内存单元中
  2. 被除数:默认放在AX或DX中如果是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 [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

你可能感兴趣的:(汇编基础知识五)