汇编语言笔记07-更灵活的定位内存地址的方法

 

转载必须注明出处,违者必究。http://www.cnblogs.com/dennisOne

 

 

小知识点1andor指令

  1. and指令

    mov al, 01100011B

    and al, 00111011B

  2. or指令

    mov al, 01100011B

    or al, 00111011B

  3. andor指令的功能(比如大小写转化,将后面的知识点)

    and:复位

    or: 置位

   

小知识点2ASCII

一种很重要的编码方式: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

 

经典:大小写转换问题

  1. 大小写字母的ASCII

  2. 程序:将'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. 定位内存的方式,称为:寻址方式。主要有:

    (1). segreg:[data]用一个常量来表达地址,可用于直接定位一个内存;

    (2).[bx]用一个变量表示内存地址,可用于间接定位一个内存单元;

    (3).[bx+idata]用一个变量和常量表示地址定位一个内存单元;

    (4).[bx+si]两个变量表示地址;

    (5).[bx+si+idata]用两个变量和一个常量表示地址。

  2. [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       
  3. [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
  4. [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). andor指令常用于复位和置位。

posted @ 2012-10-20 17:31  dennis_fan  阅读(676)  评论(0编辑  收藏  举报