我是靠谱客的博主 呆萌身影,这篇文章主要介绍汇编语言随笔(5)-and、or指令,串传送指令movsb、访问内存单元的方式及实验4,5(向内存传送数据),现在分享给大家,希望可以做个参考。

and、or指令

      and指令,逻辑与指令,按位进行与运算;or指令,逻辑或指令,按位进行或运算。
      如:mov al,01100011B
              and al,00111011B
      执行后:(al)=00100011B。用法:将操作数的某一位设置为0,其他位不变,如将al的第6位设置为0,and al 10111111B,或and al 0bfh。

      如:mov al,01100011B
                 or al,00111011B
      执行后:(al)=01111011B。用法:将操作数的某一位设置为1,其他位不变,如将al的第6位设置为1,or al 01000000B,或or al 40h。

访问内存

      1,之前提到过采用中括号‘[ ]‘来访问内存,在此对其做一补充:在汇编源程序中,如果采用常量作为内存的偏移地址时,应在前面显示加上相应的段寄存器。如:mov ax,ds:[0],来指明内存数据的段地址在ds段寄存器中,偏移地址为0;
      如果采用寄存器值作为内存的偏移地址时,则不需要这样做,如:mov bx,0         mov ax,[bx] ,这两种写法是等价的。
      其中用于显示指明内存单元的段地址的段寄存器如’ds:’、‘es:’、‘cs:’、'ss:'称为段前缀。

      2,定义数据段空间:
      db,定义字节数据(8位);dw,定义字型数据(16位);dd,定义双字型数据(32位)。
      db ‘…’,单引号中为字符串,定义字符串数据。如 db ’unIX‘ 它定义了4个字节大小的空间分别来存储’u’的ASCII值75h,’n’的ASCII值6eh,’I’的ASCII值49h,’X’的ASCII值58h。等价于 db 75h,6eh,49h,58h
      dup,常与db、dw、dd配合使用,用来进行数据的重复。例:db 3 dup(0),定义了3个字节,它们的值都是0,相当于db 0,0,0;db 3 dup(0,1,2),定义了9个字节,它们是0,1,2,0,1,2,0,1,2,相当于db 0,1,2,0,1,2,0,1,2。也可以配合 dw和dd来使用,用法都是一样的。

      3,定位内存单元的更多方法:
      [bx+idata],段地址默认在ds中,也可显式给出段地址。如:mov ax,[bx+200],将段地址在ds中,偏移地址为(bx)+200处的字型数据传送到ax中。其他等价的格式为:mov ax,[200+bx]mov ax,200[bx]mov ax,[bx].200.。同样的方式还有[si+idata]、[di+idata]、[bp+idata](含有bp的默认段地址在ss中)。
      [bx+si],段地址默认在ds中,也可显式给出段地址。如:mov ax,[bx+si],将段地址在ds中,偏移地址为(bx)+(si)处的字型数据传送到ax中。其他等价的格式为:mov ax,[bx] [si]。同样的方式还有[bx+di]、[bp+si]、[bp+di](含有bp的默认段地址在ss中)。
      [bx+si+idata],段地址默认在ds中,也可显式给出段地址。如:mov ax,[bx+si+200],将段地址在ds中,偏移地址为(bx)+(si)+200处的字型数据传送到ax中。其他等价的格式为:mov ax,[bx+200+si]mov ax,[200+bx+si]mov ax,200[bx] [si]mov ax,[bx].200[si]mov ax,[bx] [si].200。同样的方式还有[bx+di+idata]、[bp+si+idata]、[bp+di+idata](含有bp的默认段地址在ss中)。

例题

      传送数据:将内存ffff:0-ffff:b单元内的数据复制到0:200-0:20b单元中。
      方法一:采用loop指令,具体如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
assume cs:code code segment mov ax,0ffffh mov ds,ax ds保存源数据的段地址 mov ax,0020 为使得偏移地址保持一致进行转化 mov es,ax es保存目的数据的段地址 mov bx,0 bx中存储偏移地址 mov cx,0ch s:mov al,[bx] mov es:[bx],al inc bx loop s mov ax,4c00h 程序返回指令 int 21h code ends end

      方法二:采用DF标志和串传送指令
      其中df标志为flag的第10位,方向标志位。在串传送指令中,它用来控制每次操作后si、di的增减。其中当df=0时,每次操作后si、di递增;当df=1时,每次操作后si、di递减。cld指令将标志寄存器的df位设置位0;std指令将df设置为1。
      串传送指令movsb,它的功能是将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器中df位的值,将si和di递增或递减。而movsw传送的是字单元,用法与movsb类似,si、di每次加2或减2。

用法:rep movsb,根据cx中的值,重复执行串传送指令,即传送cx个字节。
      故:
      传送的原始位置:ffff:0放入ds:si中
      传送的目的位置:0:200放入es:di中
      传送的长度:0ch放入cx中
      传送的方向:正方向,从而设置df为0
      编码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
assume cs:code code segment mov ax,0ffffh mov ds,ax mov si,0 mov ax,0 mov es,ax mov di,200h mov cx,0ch cld rep movsb mov ax,4c00h int 21h code ends end

实验4

      编程实现向内存0:200-0:23F依次传送数据0-63(3FH),只能用9条指令。

复制代码
1
2
3
4
5
6
7
8
9
10
11
mov ax,0020 更改内存地址的表示方式为0020:0-0020:3f mov ds,ax mov bx,0 mov cx,64 s:mov [bx],bx inc bx loop s mov ax,4c00h int 21h

实验5

      有一条重要的结论:如果我们在定义一段栈段空间或数据段空间时,无论具体定义了多大的空间,最终被分配的空间大小都是16字节的整数倍。
      如

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
assume cs:code,ds:data,ss:stack data segment dw 0123H,0456H data ends stack segment dw 0,0 stack ends code segment ... code ends ...

      上述代码虽然定义的数据段只有两个字,4个字节大小,但是在程序加载时分配的空间为16字节,后12个字节单元中的值均为0。栈段也是如此。
      如果段中的数据占有N个字节,则程序加载后,该段实际占有的空间为(N/16+1)*16字节大小。
      (5),编写code中代码,将a段和b段中的数据依次相加,将结果存到c段中。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
assum cs:code a segment db 1,2,3,4,5,6,7,8 a ends b segment db 1,2,3,4,5,6,7,8 b ends c segment db 0,0,0,0,0,0,0,0 c ends code segment start: mov ax,a 先将a段和b段中数据相加的结果保存到a段中 mov ds,ax mov ax,b mov es,ax mov bx,0 mov cx,8 s: add byte ptr [bx],es:[bx] 每个字节相加 inc bx loop s mov ax,c 将a段中的结果保存到c段中。 mov es,ax mov bx,0 mov cx,8 s: mov byte ptr es:[bx],[bx] inc bx loop s mov ax,4x00h int 21h code ends end start

      (6),编写code中代码,用push指令将a段中的前8个字型数据,逆序存储到b段中。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
assum cs:code a segment dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh a ends b segment dw 0,0,0,0,0,0,0,0 b ends code segment start: mov ax,b mov ss,ax mov sp,10h 将b段作为栈段 mov ax,a mov ds,ax mov bx,0 mov cx,8 s: push [bx] 只需要依次入栈即可。(栈操作中的数据都为字型) add bx,2 注意:此处为加2. loop s mov ax,4x00h int 21h code ends end start

最后

以上就是呆萌身影最近收集整理的关于汇编语言随笔(5)-and、or指令,串传送指令movsb、访问内存单元的方式及实验4,5(向内存传送数据)的全部内容,更多相关汇编语言随笔(5)-and、or指令,串传送指令movsb、访问内存单元内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(81)

评论列表共有 0 条评论

立即
投稿
返回
顶部