汇编语言笔记16-直接定址表

时间:2022-06-22 01:14:04

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

地址标号和数据标号

  1. 地址标号
     1 assume cs:code
    2 code segment
    3 a: db 1, 2, 3, 4, 5, 6, 7, 8
    4 b: dw 0
    5 start: mov si, offset a
    6 mov bx, offset b
    7 mov cx, 8
    8 s: mov al, cs:[si]
    9 add cs:[bx], al
    10 inc si
    11 loop s
    12
    13 mov ax, 4c00h
    14 int 21h
    15 code ends

    程序中codeabstarts都是标号,仅仅表示内存单元的地址。

    注意:对于":"的地址标号,只能在代码段中使用,不能在其他段中使用。

  2. 数据标号(在代码段中使用数据标号)
     1 assume cs:code, ds: data
    2 code segment
    3 a db 1, 2, 3, 4, 5, 6, 7, 8
    4 b dw 0
    5 start:
    6 mov si, 0
    7 mov cx, 8
    8 s: mov al, a[si]
    9 mov ah, 0
    10 add b, ax
    11 inc si
    12 loop s
    13
    14 mov ax,4c00h
    15 int 21h
    16 code ends
    17
    18 end start

    程序中的ab是数据标号,不仅仅表示内存单元的地址,还表示了内存单元的长度。标号b代表了一个内存单元,地址为code:8长度为两个字节。所以,如果mov al, b会报错。

    数据标号在编译期间被编译器直接用地址替换了,并且进行了类型(字节操作or字操作)检查。

    比如: mov ax, b <==> mov ax, cs:[8]

    mov b, 2 <==> mov word ptr cs:[8], 2

    mov al, a[si] <==> mov al,cs:0[si]

    mov al, a[bx+si+3] <==> mov al, cs:[0][bx+si+3]

  3. 数据标号(在其他段中使用)

     

     1 assume cs:code, ds: data
    2 data segment
    3 a db 1, 2, 3, 4, 5, 6, 7, 8
    4 b dw 0
    5 data ends
    6
    7 code segment
    8 start:
    9 mov ax, data
    10 mov ds, ax
    11
    12 mov si, 0
    13 mov cx, 8
    14 s: mov al, a[si]
    15 mov ah, 0
    16 add b, ax
    17 inc si
    18 loop s
    19
    20 mov ax,4c00h
    21 int 21h
    22 code ends
    23 end start

     

    注意:在数据段中使用数据标号,需要:使用assume将数据段和ds进行关联(这样只是将默认所访问单元的段地址都在ds中,而不是cs中);将ds指定为data段的段地址。

    现在:mov al, a[si] <==> mov al, ds:[0][si]

            mov b, ax <==> mov ds:[8], ax

   

直接定址表

  1. 辅助知识:标号即是地址
     1 data segment
    2 a db 1,2,3,4,5,6,7,8
    3 b dw 0
    4 c dw a, b ;<==> c dw offset a, offset b
    5 data ends
    6
    7 data segment
    8 a db 1,2,3,4,5,6,7,8
    9 b dw 0
    10 c dd a, b ;<==> c dw offset a, seg a, offset b, seg b
    11 data ends
  2. 直接定制表

    (1). 入门题目:编写子程序,以十六进制的形式在屏幕中间显示给定的字节型数据。如11111111显示为FF

     1         ; 用al传送要显示的数据
    2 showbyte: jmp short show
    3 table db '0123456789ABCDEF' ; 字符表
    4 show:
    5 push bx
    6 push es
    7
    8 mov ah, al
    9 shr ah, 1
    10 shr ah, 1
    11 shr ah, 1
    12 shr ah, 1 ; ah-高4位
    13 and al, 00001111b ; al-第4位
    14
    15 mov bl, ah
    16 mov bh, 0
    17 mov ah, table[bx] ; 高4位对应的字符
    18
    19 mov bx, 0b8000h
    20 mov es, bx
    21 mov es:[160*12+40*2], ah
    22
    23 mov bl, al
    24 mov bh, 0
    25 mov ah, table[bx] ; 低4位对应的字符
    26
    27 mov es:[160*12+40*2+2], al
    28
    29 push es
    30 push bx
    31
    32 ret

    可以看出,直接定址表的好处:*算法更加清晰和简介;加快运算速度;程序更易扩展。

    (2). 进阶题目:showsin

     1         showsin:
    2 jmp short show
    3 ; 字符串偏移地址表
    4 table dw ag0, ag30, ag60, ag90, ag120, ag150, ag180
    5 ag0 db '0', 0
    6 ag30 db '0.5', 0
    7 ag60 db '0.866', 0
    8 ag90 db '1', 0
    9 ag120 db '0.866', 0
    10 ag150 db '0.5', 0
    11 ag180 db '0', 0
    12
    13 show:
    14 push bx
    15 push es
    16 push si
    17
    18 mov bx, 0b800h
    19 mov es, bx
    20
    21 ; 以下用角度值/30作为相对于table的偏移,取得对应的字符串的偏移地址
    22 mov ah, 0
    23 mov bl, 30
    24 div bl
    25 mov bl, al
    26 mov bh, 0
    27 add bx, bx
    28 mov bx, table[bx]
    29
    30 ; 显示字符串
    31 mov si, 160*12+40*2
    32 shows: mov ah, cs:[bx]
    33 cmp ah, 0
    34 je showret
    35 mov es:[si], ah
    36 inc bx
    37 add si, 2
    38 jmp short shows
    39
    40 showret: pop si
    41 pop es
    42 pop bx
    43
    44 ret

    (3). 编写子程序:类似于dll的方式。<微软的处理 方式>

     

      1         ; 入口参数说明:
    2 ; (1).用ah寄存器传递功能号:0表示清屏, 1表示设置前景色,2表示设置背景色,3表示向上滚动一行
    3 ; (2).对于2、3号功能,用al传递颜色值,(al)属于{0,1,2,3,4,5,6,7}
    4
    5 ; ------------------------------- 类似于dll -------------------------------
    6 setscreen: jmp short set
    7 table dw sub1, sub2, sub3, sub4, sub5
    8 set: push bx
    9
    10 cmp ah, 4
    11 ja sret
    12
    13 mov bl, ah
    14 mov bh, 0
    15 add bx, bx
    16
    17 call word ptr table[bx] ; 调用对应的功能子程序
    18
    19 sret: pop bx
    20 ret
    21
    22 ; -------------------------------- 子程序 --------------------------------
    23 ; 功能子程序: 清屏
    24 sub1:
    25 push bx
    26 push cx
    27 push es
    28 mov bx, 0b800h
    29 mov es, bx
    30 mov bx, 0
    31 mov cx, 2000
    32 sub1s: mov byte ptr es:[bx], ' '
    33 add bx, 2
    34 loop sub1s
    35 pop es
    36 pop cx
    37 pop bx
    38 ret
    39
    40 ; 功能子程序: 设置前景色
    41 sub2:
    42 push bx
    43 push cx
    44 push es
    45 mov bx, 0b800h
    46 mov es, bx
    47 mov bx, 0
    48 mov cx, 2000
    49 sub2s: and byte ptr es:[bx], 11111000b
    50 or es:[bx], al
    51 add bx, 2
    52 loop sub2s
    53
    54 pop es
    55 pop cx
    56 pop bx
    57 ret
    58
    59 ; 功能子程序: 设置背景色
    60 sub3:
    61 push bx
    62 push cx
    63 push es
    64
    65 mov cl, 4
    66 shl al, cl
    67 mov bx, 0b800h
    68 mov es, bx
    69 mov bx, 1
    70 mov cx, 2000
    71 sub3s: and byte ptr es:[bx], 10001111b
    72 or es:[bx], al
    73 add bx, 2
    74 loop sub3s
    75
    76 push es
    77 push cx
    78 push bx
    79 ret
    80
    81 ; 功能子程序: 向上滚动一行
    82 sub4:
    83 push cx
    84 push si
    85 push di
    86 push es
    87 push ds
    88
    89 mov si, 0b800h
    90 mov es, si
    91 mov ds, si
    92 mov si, 160
    93 mov di, 0
    94
    95 cld
    96 mov cx, 24
    97
    98 sub4s: push cx
    99 mov cx, 160
    100 rep movsb
    101 pop cx
    102 loop sub4s
    103
    104 ; 清空最后一行
    105 mov si, 0
    106 mov cx, 80
    107 sub4s1: mov byte ptr [160*24+si], ' '
    108 add si, 2
    109 loop sub4s1
    110
    111 pop ds
    112 pop es
    113 pop di
    114 pop si
    115 pop cx
    116 ret
    117
    118 ; 功能子程序: 向下滚动一行
    119 sub5:
    120 mov si, 0b800h
    121 mov es, si
    122 mov ds, si
    123 mov si, 0
    124 mov di, 160
    125
    126 cld
    127 mov cx, 24
    128
    129 sub5s: push cx
    130 mov cx, 160
    131 rep movsb
    132 pop cx
    133 loop sub5s
    134
    135 ; 清空第一行
    136 mov si, 0
    137 mov cx, 80
    138 sub5s1: mov byte ptr [si], ' '
    139 add si, 2
    140 loop sub5s1