汇编学习笔记(4)寻址方式

前言

本文是《汇编语言》的学习笔记,对应书中第七章内容,灵活的寻址方式。

这一章节主要通过例题的形式介绍汇编中访问内存的多种方式,新介绍了and和or命令,si,di寄存器。

and

and命令是逻辑与命令,按二进制位进行与运算。与运算就是q与q的合取式记为p^q,p和q只要有一个为假,p^q就为假,当且仅当q和q都为真时,p^q才为真。用二进制表示,当且仅当p和q都为0时,p^q才为0,所以

mov al,01100000b

and al,00110000b

结果等于00100000b.

or

or命令是逻辑或命令,按二进制位进行或运算。或运算就是q或q的析取式记为pVq,p或q只要有一个为真,pVq就为真,当且仅当q和q都为假时,pVq才为假。用二进制表示,当且仅当p和q都为1时,pVq才为1,所以

mov al,01100000b

or al,00110000b

结果等于01110000b.

si和di

si和di是8086CPU中和bx功能相近的寄存器,不同的是si和di不能拆分为两个8位寄存器,即没有sh,sl,dh,dl,si和di多和bx搭配表示地址。

内存地址的表示方式

程序的设计大部分是对数据的处理,数据一般存储在内存当中,所以对内存单元的寻址能力尤其重要。数据段的段地址一般保存在寄存器ds中,故在偏移地址的表示方面可以有多种方式,假设ds=1000h

1.[idata],设idata=10h,则内存单元地址为ds:[10]=10010h

2.[bx],设(bx)=10h,则内存单元地址为ds:[bx]=10010h

3.[bx+idata],idata[bx],[bx].idata,设(bx)=10h,idata=10h,则内存单元地址为ds:[bx+idata]=10020h

4.[bx+si],[bx+di],[bx][si],[bx][di],设(bx)=10h,(si)=10h,则内存单元地址为ds:[bx][si]=10020h

5.[bx+si+idata],[bx+di+idata],idata[bx][si],idata[bx][di],设(bx)=10h,(si)=10h,idata=10h,则内存单元地址为ds:idata[bx][si]=10030h

几个例子

  • 将小写字符改为大写,大写字符改为小写
 1 ;将第一个字符串变为大写,第二个字符串变为小写
 2 
 3 assume cs:code,ds:data
 4 
 5 data segment
 6     db 'unix'
 7     db 'FORK'
 8 data ends
 9 
10 code segment
11 start:  mov ax,data
12         mov ds,ax
13         mov bx,0
14         mov cx,4
15 s:      mov al,0[bx];等同[bx+0]
16         and al,11011111b;与运算,第五位置为0,大写
17         mov 0[bx],al
18         mov al,4[bx];偏移地址为bx+4,内存地址为(ds)*16+(bx)+4
19         or al,00100000b;或运算,第五位置为1,小写
20         mov 4[bx],al
21         inc bx
22         loop s
23 
24         mov ax,4c00h
25         int 21h
26 
27 code ends
28 
29 end start

 

大家可以看到上面的例子中,偏移地址的表示方式0[bx],5[bx]和C语言中的数组表示array[0],array[5]非常相像,C语言的数组可以理解为对数组首元素的偏移量。

  • 将字符串的首字母大写
 1 ;将字符串首字母大写
 2 
 3 assume cs:code,ds:data
 4 
 5 data segment
 6     db '1.file          '
 7     db '2.folder        '
 8     db '3.path          '
 9 data ends
10 
11 code segment
12 start:  mov ax,data
13         mov ds,ax
14         mov bx,0
15         mov si,2
16         mov cx,3
17 s:      mov al,[bx][si]
18         and al,11011111b
19         mov [bx][si],al
20         add bx,16
21         loop s
22 
23         mov ax,4c00h
24         int 21h
25 
26 code ends
27 
28 end start

 

  • 将每个字符串改为大写字母
 1 ;将字符串改为大写
 2 
 3 assume cs:code,ds:data,ss:stack
 4 
 5 data segment
 6     db 'file            '
 7     db 'name            '
 8     db 'path            '
 9 data ends
10 
11 stack segment
12     dw 0,0,0,0,0,0,0,0
13 stack ends
14 
15 code segment
16 start:  mov ax,stack
17         mov ss,ax
18         mov sp,16;指向栈顶
19         mov ax,data
20         mov ds,ax
21         mov bx,0
22         mov cx,3
23 s:      push cx
24         mov si,0 
25 
26         mov cx,4
27 s0:     mov al,[bx][si]
28         and al,11011111b
29         mov [bx][si],al
30         inc si
31         loop s0
32 
33         pop cx
34         add bx,16
35         loop s
36 
37         mov ax,4c00h
38         int 21h
39 
40 code ends
41 
42 end start

 

posted @ 2013-12-17 22:31  huntstack  阅读(628)  评论(0编辑  收藏  举报