汇编程序-更灵活的定位内存地址方法

汇编程序-更灵活的定位内存地址方法

如何灵活运用定位内存的方法呢?在之后,我们将列出几个实际例子。通过例子,展示定位内存的一些方法,熟悉和提升我们对汇编程序的理解。


大小写转化(1)

通过上面的汇编程序,我们完成了将data段中存放的『basIc』转化为了『BASIC』,将『MinIX』转化为了『minix』

assume cs:code

data segment
    db 'basIc'
    db 'MinIX'
data ends


code segment 

start:  
    mov ax,data
    mov ds,ax

    mov bx,0
    mov si,0    ;表示起始位置,这里起始位置为0

    ;观察ASCII码表,对比大小写字母的二进制形式,
    ;发现除了第5位外,大写小字母的其他各个位数都是一样的。
    ;大写字母的第5位为0,小写字母的第5位为1。
    ;因此,转化大小写,只要对第5位数进行逻辑运算即可
    mov cx,5
s:  mov al,[si+bx]
    and al,11011111B
    mov [bx],al
    mov al,[si+5+bx]
    or al,00100000B
    mov [5+bx],al
    inc bx
loop s

    mov ax,4c00H
    int 21H

code ends

end start

如图:

知识点

  1. and表示逻辑与运算。

    mov al,10101100B
    and al,11011111B
    
    //结果 al = 10001100B
  2. or表示逻辑或运算。

    mov al,10001100B
    or  al,00100000B
    
    //结果 al = 10101100B
  3. db ‘……’为以字符的形式给出数据。编辑器讲他们转化为相对应的ASCII码,一个单词为一个字节大小。

  4. [idata+bx]

    在前面,我们用[bx]的方式来指明一个内存单元,还可以用一种更为灵活的方式来指明内存单元:[idea+bx]表示一个内存单元,他的偏移地址为(bx)+idata(bx中的数值加上idata)。

    常用格式:

    mov ax,[200+bx]
    mov ax,200[bx]//模拟高级语言写法(类似于c语言中的a[10])
    mov ax,[200].bx//模拟高级语言写法
  5. si,di寄存器
    si,di是和bx功能相近的寄存器。下面展示了几种使用方法:

    • mov ax,[si] /mov ax,[bi]
    • mov ax,[bx][si] / mov ax,[bx][bi]
    • mov ax,[bx+si+10]/ mov ax,200[bx][si]/ mov ax,[bx].200[si]/ mov ax,bx[si].200


大小写转化(2)

通过下面的汇编程序,我们完成了将data段中存放的4条字符串中的小写字母转化为了大写字母

assume cs:code, ds:data, ss:stack

data segment
    db 'ibm             '   
    db 'dec             '
    db 'vox             '
    db 'vax             '
data ends

stack segment
    dw 0,0
stack ends


code segment

start:
    mov ax,stack
    mov ss,ax
    mov sp,16
    mov ax,data
    mov ds,ax
    mov bx,0

    mov cx,4

s0: push cx
    mov si,0
    mov cx,3

    s:  mov al,[bx+si]
        and al,11011111B
        mov [bx+si],al
        inc si
    loop s

    add bx,16
    pop cx
loop s0
    mov ax,4c00H
    int 21H


code ends

end start   

code ends

end start

如图:

知识点

  1. 通过栈来存放数据

    例如:上面程序中进行了嵌套循环,但是技术寄存器cx只有一个。怎么做到将cx存储一分为二使用呢?我们可以通过栈来将cx中的数据存储到内存单元中。外层循环中,我们通过cx来进行循环计数;在进入内层loop之前,将外层的loop中的cx,push存放起来,再重新设置cx,进行内部loop;当内层loop完毕,通过pop将cx中的数取出来,继续外部loop中的操作。

  2. 循环嵌套

    s0: push cx
    
    ...
    
        s:  mov al,[bx+si]
            ...
            ...
            ...
        loop s
    
    pop cx
    loop s0


大小写转化(3)

'1. display      '  
'2. brows        '
'3. replace      '
'4. modify       '

将上面4个字符串中的小写单词转化为大写单词。

代码如下

assume cs:code, ds:data, ss:stack

data segment
    db '1. display      '   
    db '2. brows        '
    db '3. replace      '
    db '4. modify       '
data ends

stack segment
    dw 0,0
stack ends


code segment

start:  
    mov ax,stack
    mov ss,ax
    mov sp,10H

    mov ax,6H
    push ax
    mov ax,7H
    push ax
    mov ax,5H
    push ax
    mov ax,7H
    push ax

    mov ax,data
    mov ds,ax
    mov bx,3H
    mov si,0H

    mov cx,4H
s1: mov dx,cx
    pop cx
    push dx

        mov si,0H
    s2: mov al,[bx+si]
        and al,11011111B
        mov [bx+si],al
        inc si
    loop s2

    add bx,10H
    pop cx
loop s1

    mov ax,4c00H
    int 21H
code ends
end start

效果图

posted @ 2015-11-08 17:29  AbeDay  阅读(170)  评论(0编辑  收藏  举报