内存地址定位方法

1.and 和 or 指令
and    ->用来做逻辑与运算
    例如:
mov ax,0011B
and ax,0001B
    结果:ax 中的值为0001B
        
or    ->逻辑或运算
    指令:
mov ax,0011B
or ax,1100B
    结果:1111B
 
2.字符型数据
伪指令db(define byte)可用来定义字节型数据;
例如:
db 5
 
可以使用伪指令db来定义字符型数据;
格式为:db '字符串'
db 'HelloWorld'
db 'a'
用单引号括起来'......'的方式表示数据以字符的方式给出,编译器会将其中的字符转换成它们对应的ASCII码;
例如:db 'u' 相当于 db 75H;
 
1)关于大小写转换
通过查ASCII表可知:大写字符+20H=小写字符;
例如:将hello 转换成HELLO
assume cs:code,ds:data
 
data segment
    db 'HELLO'    ;定义字符串大写的HELLO
data ends
 
code segment
start:    mov ax,data    ;程序入口
        mov ds,ax    ;将段寄存器ds指向数据段data
        mov bx,0    ;偏移地址设为0
    
        mov cx,5    ;设置循环次数
    s:    add byte ptr [bx],20h;转换成大写,根据ascii码:'A'+20h='a',byte ptr 表示传送的时字符型数据,word ptr表示字型数据
        inc bx        ;偏移地址自增1
        loop s        ;从标记s处循环
        
        mov ax,4c00h;程序返回
        int 21h
 
code ends
end start
也可以利用and和or来转换大小写:
例如:a 和 A之间的转换
ascii码:
    a    ->01100001
    A    ->01000001
可以看出第六位的0和1决定了a的大小写;
利用and和or可以改变某一位的值;
a转A:
mov al,01100001b
and al,11011111b
A转a:
mov al,01000001b
or al,00100000b
 
3.[bx+idata]
[bx]可以用来表示内存单元的偏移地址;
[bx+idata]表示偏移地址为bx中的值+idata的值;
例如:
mov ax,[bx+5]
其它表示方式:
mov ax,0[bx]    ;相当于 mov ax,[0+bx]
mov ax,5[bx]    ;相当于 mov ax,[5+bx]
 
4.SI和DI
si和di寄存器和bx寄存器的用法相似,可用来表示偏移地址;
但si和di不能被拆分成两个8位寄存器来使用;
例如:下面的三条指令功能相同
mov ax,[bx+123]
mov ax,[si+123]
mov ax,[di+123]
 
也可以将si和di与bx混合使用:[bx+si]、[bx+di]
mov ax,[bx+si]
mov ax,[bx+di]
 
si和di与bx以及idata混用:[bx+si+idata]、[bx+di+idata]
mov ax,[bx+si+6]
该指令的其它表示方式:
mov ax,[bx][si].6
mov ax,6[bx][si]
mov ax,[bx].6[si]
 
5.不同寻址方式的灵活运用
比如:某个程序需要进行其嵌套循环时;
    因为循环需要用到cx寄存器;
    而内层循环会改变cx的值,而影响外层循环;
    可以考虑将cx的值在进入内层循环前保持起来,在内存循环结束后,再重新赋给cx;
    可以用另一个寄存器,比如dx来保存;
    但是可能程序太复杂,而寄存器数量有限,比如dx被占用了;
    可以用将cx的值保持在内存中,而不是用寄存器来保存;
    具体做法是:在数据段中用dw定义一个字,用来保存cx的值;
    这样做也有个问题:当需要保存多个数据时,必须记住数据保存到了哪个空间,容易混淆;
    为了让程序更加清晰:一般来说在需要暂存数据时,我们都应该使用栈;
 
例如:分别将下面四个字符串的前三个字母转为大写
assume cs:code,ds:data,ss:stack
data segment
    db 'one3456789abcde'
    db 'two3456789abcde'
    db 'thr3456789abcde'
    db 'fou3456789abcde'
data ends
 
stack segment
    dw '0,0,0,0,0,0,0,0'    ;定义一个16个字节的栈段
segment ends
 
code segment
    start:mov ax,data
        mov ds,ax
        mov bx,0
 
        mov ax,stack
        mov ss,ax
        mov sp,16    ;ss:sp指向栈顶
    
        mov cx,4
    s:push cx    ;将外层cx的值入栈
        mov si,0
        mov cx,3
    s0:mov al,[bx+si]    
        and al,11011111b
        mov [bx+si],al
        inc si
        loop s0    ;内层循环
        
        add bx,16
        pop cx    ;从栈中弹出cx的值,恢复外层循环计数
        loop s    ;外层循环
           
 
    mov ax,4c00h
    int 21h
code ends
end start
 
 
 
posted @ 2019-06-26 16:40  L丶银甲闪闪  阅读(437)  评论(0编辑  收藏  举报