前言
本文是《汇编语言》的学习笔记,对应书中第七章内容,灵活的寻址方式。
这一章节主要通过例题的形式介绍汇编中访问内存的多种方式,新介绍了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