汇编语言笔记07-更灵活的定位内存地址的方法
转载必须注明出处,违者必究。http://www.cnblogs.com/dennisOne
小知识点1:and和or指令
-
and指令
mov al, 01100011B
and al, 00111011B
-
or指令
mov al, 01100011B
or al, 00111011B
-
and和or指令的功能(比如大小写转化,将后面的知识点)
and:复位
or: 置位
小知识点2:ASCII码
一种很重要的编码方式:ASCII(American Standard Code for Information Interchange, ASCII )
小知识点3:以字符形式给出的数据
在汇编语言中,使用'…'的方式指明数据以字符的形式给出,编译器将它们转化为对应的ASCII码。
例:
1 assume cs:code, ds:data 2 data segment 3 db 'unIX' ; 等价于 db 75H, 6EH, 49H, 58H 4 db 'foRK' ; 等价于 db 66H, 6FH, 52H, 4BH 5 data ends 6 code segment 7 start: mov al, 'a' ; 等价于 mov al, 61H 8 mov bl, 'b' ; 等价于 mov al, 62H 9 10 mov ax, 4c00h 11 int 21h 12 code ends 13 end start
经典:大小写转换问题
- 大小写字母的ASCII码
-
程序:将'BaSic'编程大写的,将'iNfOrMaTion'编程小写的。
1 assume cs:code, ds:data 2 data segment 3 db 'BaSic' 4 db 'iNfOrMaTion' 5 data ends 6 7 code segment 8 start: mov ax, data 9 mov ds, ax 10 11 mov bx, 0 12 13 mov cx,5 14 s: mov al, [bx] 15 and al, 11011111B ;将al的ASCII码的第5位置为0,变成大写字母 16 inc bx 17 loop s 18 19 mov cx, 11 20 s0: mov al, [bx] 21 or al, 00100000B ;将al的ASCII码的第5位置为1,变成小写字母 22 inc bx 23 loop s0 24 25 mov ax, 4C00H 26 int 21h 27 28 code ends 29 end start
各种寻址方式(更加详细的见下章)
-
定位内存的方式,称为:寻址方式。主要有:
(1). segreg:[data]用一个常量来表达地址,可用于直接定位一个内存;
(2).[bx]用一个变量表示内存地址,可用于间接定位一个内存单元;
(3).[bx+idata]用一个变量和常量表示地址定位一个内存单元;
(4).[bx+si]两个变量表示地址;
(5).[bx+si+idata]用两个变量和一个常量表示地址。
-
[bx]和[bx+idata]:进行数组的处理
例:将data段中每个单词的头一个字母改写成大写字母。
1 assume cs:code, ds:data 2 data segment 3 db '1. file ' 4 db '2. edit ' 5 db '3. search ' 6 db '4. view ' 7 db '5. options ' 8 db '6. help ' 9 data ends 10 11 code segment 12 start: mov ax, data 13 mov ds, ax 14 mov bx, 0 15 mov cx, 6 16 s: mov al, [bx+3] 17 and al, 11011111b 18 mov [bx+3], al 19 add bx, 16 20 loop s 21 22 code ends 23 end start
-
[bx+si]和[bx+di]:处理双层循环
例:将data段中每个单词都改写成大写字母。
1 ;双层循环要注意共用cx,要注意cx的保存与恢复。 2 assume cs:code, ds:data 3 4 data segment 5 db 'ibm ' 6 db 'dec ' 7 db 'doc ' 8 db 'vax ' 9 data ends 10 11 code segment 12 start: mov ax, data 13 mov ds, ax 14 mov bx, 0 ; 外层循环的指标 15 mov cx, 4 16 s0: mov dx, cx ; 保存cx 17 mov si, 0 ; 内存循环的指标 18 mov cx, 3 19 20 s: mov al, [bx+si] 21 and al, 11011111b 22 mov [bx+si], al 23 inc si 24 loop s 25 26 add bx, 8 27 mov cx, dx ; 恢复cx 28 loop s0 29 30 mov ax, 4c00h 31 int 21h 32 code ends 33 end start
改进:规范的程序都是使用stack进行数据的保存。
改进代码:
1 assume cs:code, ds:data, ss:stack 2 3 data segment 4 db 'ibm ' 5 db 'dec ' 6 db 'doc ' 7 db 'vax ' 8 data ends 9 10 stack segment 11 dw 0, 0, 0, 0, 0, 0, 0, 0 ;定义一个容量为16个字节的栈 12 stack ends 13 14 code segment 15 start: mov ax, stack 16 mov ss, ax 17 mov sp, 16 18 mov ax, data 19 mov ds, ax 20 mov bx, 0 21 22 mov cx, 4 23 s0: push cx ; 保存cx 24 mov si, 0 25 mov cx, 3 26 27 s: mov al, [bx+si] 28 and al, 11011111b 29 mov [bx+si], al 30 inc si 31 loop s 32 33 add bx, 16 34 pop cx ; 恢复cx 35 loop s0 36 37 mov ax, 4c00h 38 int 21h 39 code ends 40 end start
-
[bx+si+idata]和[bx+di+idata]
例:将data段的首四个字母改成大写。
1 assume cs:code, ds:data, ss:stack 2 3 data segment 4 db '1. display ' 5 db '2. brows ' 6 db '3. replace ' 7 db '4. modify ' 8 data ends 9 10 stack segment 11 dw 0, 0, 0, 0, 0, 0, 0, 0 12 stack ends 13 14 code segment 15 start: mov ax, stack 16 mov ss, ax 17 mov sp, 16 18 mov ax, data 19 mov ds, ax 20 mov bx, 0 21 22 mov cx, 4 23 s0: push cx ;保存cx 24 mov si, 0 25 mov cx, 4 26 27 s: mov al, [bx+si+3] 28 and al, 11011111b 29 mov [bx+si+3], al 30 inc si 31 loop s 32 33 add bx, 16 34 pop cx ;恢复cx 35 loop s0 36 37 mov ax, 4c00h 38 int 21h 39 code ends 40 end start
总结:
(1). [bx]和[bx+idata]用于进行数组的处理; [bx+si/di]和[bx+si/di+idata]用于双层循环的场合,此外[bx+si/di+idata]可以方便进行类结构体的处理。
(2). 双层循环用于loop指令公用cx寄存器。所以需要注意cx寄存器的保存和恢复。
(3). 栈常用于数据的保存和恢复。下一讲将介绍bp将更加强大。
(4). and和or指令常用于复位和置位。