zoukankan      html  css  js  c++  java
  • 汇编语言:第七章 更灵活定位内存地址的方法

    7.1 and 和 or 指令

      二进制的and or 可以将某位归0或置1

    7.2 关于ASCII码

    7.3 以字符形式给出数据

      data segment

        db 'unIX'                    //相当于db 75H,6EH,49H,58H

        db 'foRK'       //相当于db 66H,6FH,52H,4BH

      data ends

      mov al,'a'          //相当于mov al,61H

    7.4 大小写转换问题

    db 'BaSiC'

    db 'iNfOrMaTiOn'

    如何将第一个字符串转成大写,第二个小写?

    我们将ASCII码拿出来对比一下:

    大写    十六进制    二进制        小写    十六进制    二进制

    A      41      010000001      a      61     01100001

    B      42      010000010      b        62      01100010

    C      43      010000011      c        63      01100011

    .....                        ........

    易知:小写字母比大写字母大20H,二进制中即第五位(位从0开始)为1和0

    由于我们没有条件判断的指令来+或—20H来改变大小写,所以在这里用and 和 or指令改变二进制第六位数值来达到目的:

    assume cs:code,ds:data
    data segment
    db 'BaSiC'
    db 'iNfOrMaTiOn'
    data ends
    code segment
    start:
    mov ax,data
    mov ds,ax
    mov bx,0
    mov cx,5
    s:
    mov al,ds:[bx]
    and al,11011111B    //第一个循环,前5个内存单元第五位归0  变大写
    mov ds:[bx],al
    inc bx
    loop s

    mov cx,11
    s2:
    mov al,ds:[bx]
    or al,00100000B    //第一个循环,后11个内存单元第五位置1 变小写
    mov ds:[bx],al
    inc bx
    loop s2

    mov ax,4c00h
    int 21h
    code ends
    end start

    7.5 [bx+idata]

    用bx+idata来更灵活的指定偏移地址,也可以写成 idata[bx]很方便的用于表示数组(起始位置在idata,索引在bx)

    7.6 用[bx+idata]处理数组

    assume cs:code,ds:data          //C语言
    data segment
    db 'BaSiC'            //char  a[5] = "BaSiC";
    db 'MinIX'            // char b[5] = "MinIX";
    data ends
    code segment
    start:
    mov ax,data
    mov ds,ax
    mov bx,0          // int i = 0;
    mov cx,5
    s:              //do{
    mov al,ds:0[bx]
    and al,11011111B      // a[bx] = a[bx] & 0xdf
    mov ds:[bx],al


    mov al,ds:5[bx]
    or al,00100000B      //     b[bx] = b[bx] | 0x20
    mov ds:5[bx],al
    inc bx            // i++;
    loop s           //while (i < 5)

    mov ax,4c00h
    int 21h
    code ends
    end start

     7.7 SI 和 DI

    SI 和 DI是与BX功能类似的寄存器,但是它们不能拆成两个8位寄存器

    相同点:   mov ax,[bx]   mov ax,[si]   mov ax,[di]

         mov ax,[bx+idata]   mov ax,[si+idata]   mov ax,[di+idata]

    练习:把 'welcome to masm!' 复制到它下面的内存单元中,利用si,di

    assume cs:code,ds:data

    data segment
    db 'welcome to masm!'
    db '................'
    data ends

    code segment
    start:
    mov ax,data
    mov ds,ax
    mov si,0
    mov di,16        //si和di表示数组的2个index变量,放入循环
    mov cx,16
    s:
    mov al,ds:[si]
    mov ds:[di],al
    inc si
    inc di
    loop s

    mov ax,4c00h
    int 21h
    code ends
    end start

    简化程序;

    assume cs:code,ds:data

    data segment
    db 'welcome to masm!'
    db '................'
    data ends

    code segment
    start:
    mov ax,data
    mov ds,ax
    mov si,0
    mov cx,8                //利用idata[si]减少一个index参数
    s:
    mov ax,ds:[si]
    mov ds:16[si],ax
    add si,2
    loop s

    mov ax,4c00h
    int 21h
    code ends
    end start

     7.8  [bx+si] 和 [bx+di]

    mov ax,[bx+si]   =  mov ax,[bx][si]

    7.9   [bx+si+idata] 和 [bx+di+idata]

    7.10  不同寻址方式的灵活应用

    实例一:  把每个单词首字母大写

    思路:定义一个变量用于循环每一字符串,另一个idata用于定位改字符串第3个位置(即该字符串第一个字母)

    assume cs:code,ds:data

    data segment        //注意 每个字符串都是16位
    db '1. file         '
    db '2. edit         '
    db '3. search       '
    db '4. view         '
    db '5. options      '
    db '6. help         '
    data ends

    code segment
    start:
    mov ax,data
    mov ds,ax
    mov bx,0
    mov cx,6
    s:
    mov al,ds:[bx+3]
    and al,11011111B
    mov ds:[bx+3],al
    add bx,16
    loop s

    mov ax,4c00h
    int 21h
    code ends
    end start

    实例二: 把单词变成大写

    思路:显然是需要一个嵌套循环,如何处理cx被覆盖?  使用dx暂存外部循环的次数,在内层循环完成时,把dx返回给外层的cx

    assume cs:code,ds:data

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

    code segment
    start:
    mov ax,data
    mov ds,ax
    mov bx,0
    mov cx,4
    s0:
    mov dx,cx
    mov si,0
    mov cx,3
    s:
    mov al,ds:[bx+si]
    and al,11011111B
    mov ds:[bx+si],al
    inc si
    loop s
    add bx,16
    mov cx,dx
    loop s0

    mov ax,4c00h
    int 21h
    code ends
    end start

    实例二中利用dx保存外部循环计数以便内部循环改变cx之后还能正常使用,但是我们的寄存器数量是很有限的,可以利用内存来存储变量

    assume cs:code,ds:data

    data segment
    db 'ibm             '
    db 'dec             '
    db 'dos             '
    db 'vax             '
    dw 0              //定义字型内存单元 用于存储cx值
    data ends

    code segment
    start:
    mov ax,data
    mov ds,ax
    mov bx,0
    mov cx,4
    s0:
    mov ds:[40H],cx
    mov si,0
    mov cx,3
    s:
    mov al,ds:[bx+si]
    and al,11011111B
    mov ds:[bx+si],al
    inc si
    loop s
    add bx,16
    mov cx,ds:[40H]
    loop s0

    mov ax,4c00h
    int 21h
    code ends
    end start

    利用内存的确可以保存变量值,但是这种做法还是比较不方便,实际上一般情况下 需要暂存数据的时候都用栈来保存.

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

    data segment
    db 'ibm             '
    db 'dec             '
    db 'dos             '
    db 'vax             '
    data ends
    stack segment        //定义一个16字节长度的栈
    dw 0,0,0,0,0,0,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        //cx值入栈
    mov si,0
    mov cx,3
    s:
    mov al,ds:[bx+si]
    and al,11011111B
    mov ds:[bx+si],al
    inc si
    loop s
    add bx,16
    pop cx        //出栈放到cx中
    loop s0

    mov ax,4c00h
    int 21h
    code ends
    end start

    练习:把data段中每个字符串前4个字母改成大写

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

    stack segment
    dw 0,0,0,0,0,0,0,0
    stack ends

    data segment
    db '1. display      '
    db '2. brows        '
    db '3. replace      '
    db '4. modify       '
    data 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,3
    mov cx,4
    s:
    mov al,ds:[bx+si]
    and al,11011111B
    mov ds:[bx+si],al
    inc si
    loop s
    pop cx
    add bx,16
    loop s0

    mov ax,4c00h
    int 21h
    code ends
    end start

  • 相关阅读:
    爬虫学习
    手刃爬虫豆瓣
    爬虫学习
    爬虫学习
    安卓学习新
    安卓知识点
    随手快递app开发的第十天
    随手快递app冲刺2开发的第九天
    随手快递app冲刺2开发的第八天
    随手快递app冲刺2开发的第七天
  • 原文地址:https://www.cnblogs.com/superzhao/p/4636489.html
Copyright © 2011-2022 走看看