zoukankan      html  css  js  c++  java
  • 直接定址表

    1.数据标号
    关于标号:
        在汇编代码中,可以用标号表示该段代码的内存地址;
        标号格式为,标号名加冒号    ->"start:"
        例如:下面的代码中 start: 就是标号;
    start:mov ax,0
        mov bx,ax
     
    关于数据标号:
        普通的标号只能表示内存地址;
        数据标号即可表示内存地址,也可表示内存单元的长度;
        使用数据标号可以以更加简洁的方式访问内存中的数据;
        数据标号的格式为:只有标号名,没有冒号
     
        例如:使用数据标号,实现数值的累加
    assume cs:code
    code segment
        a db 1,2,3,4,5
        b dw 0
     
        start:mov si,0
                mov cx,5
        s:     mov al,a[si] 
                mov ah,0
                add b,ax
                inc si
                loop s
        mov ax,4c00h
        int 21h
    code ends
    end start
        在上面的代码中,a、b为数据标号;
        可以使用类似a[si] 的方式获取标号a处偏移量为si的值的数据;
        注意数据标号的类型,例如上面的a时字节型数据单元,不能使用字型单元的mov指令;
     
    2.在其它段中使用数据标号
    普通的标号只能在代码段中使用;例如标号"s:"出现在数据段中会报错;
    一般情况下会将数据段和代码段分开,并且在数据段中保存数据,在代码段中保存代码,此时普通标号无法满足访问数据的需要;
    使用数据标号可以解决标号无法在其它段中的问题;
     
    例如:
    assume cs:code,ds:data
    data segment
        a db 1,2,3,4,5
        b dw 0
    data ends
     
    code segment
        start:  mov ax,data
                mov ds,ax
                mov si,0
                mov cx,5
        s:      mov al,a[si]
                mov ah,0
                add b,ax
                inc si
                loop s
        mov ax,4c00h
        int 21h
    code ends
    end start
     
    注意:
        如果想要在代码段中使用标号访问数据段,需要使用伪指令assume将段寄存器和标号所在段关联;
        assume的关联是为了让编译器可以识别标号所在段的段地址在哪个寄存器中,实际代码中还需要将段寄存器指向对应的段;
        比如:上面的代码中,想要使用数据标号a、b,用assume伪指令关联ds和data;
            但assume只是将关联告诉了编译器,实际的代码段中还需要用mov ax,data和mov ds,ax指令来将ds指向data;
     
    使用数据标号:储存两个数据标号的段地址和偏移地址
    data segment
        a db 1,2,3,4,5
        b dw 0
        c dd a,b
    data ends
    相当于:
    data segment
        a db 1,2,3,4,5
        b dw 0
        c dw offset a,seg a,offset b,seg b
    data ends
    seg功能为取得某一标号的段地址;
     
    3.直接定址表
    在编程时常会遇到一些比如用给出的数据通过计算来获得结果的问题;
    例如:将一个数转换成十六进制显示;
    当一次需要转换的数字很多时,需要多次进行重复的计算转换;
    为了简化操作,可以将问题转换为用给出的数据作为查表的依据,通过查表获得结果;
    具体操作是,建一张数据和结果映射表;用数据为条件,计算结果在表中的位置,也就获取了结果;
    例如:将0~F对应的ascii码放入一个数据段中,根据所给数值的大小来计算该数值对应的ascii在数据段中的地址;这样就不用每次都做将数值转换成ascii的操作;
    这种可以依据数据,直接计算出所要找的元素的位置的表称为直接定址表;
     
    直接定址表的应用示例代码:
    assume cs:code
     
    code segment
        start:    mov al,15
                call showbyte
        
        mov ax,4c00h
        int 21h
        
        showbyte:    jmp short show
                table db '0123456789ABCDEF'
     
     
        show:   push bx
                push es
     
                mov ah,al        ;用al传送要显示的数据
                shr ah,1            ;右移一位
                shr ah,1
                shr ah,1
                shr ah,1
                and al,00001111b
                
                mov bl,ah
                mov bh,0
                mov ah,table[bx]
     
     
                mov bx,0b800h
                mov es,bx
                mov es:[160*12+40*2],ah        ;显示高4位
                
                mov bl,al
                mov bh,0
                mov al,table[bx]
                
                mov es:[160*12+40*2+2],al        ;显示低4位
     
     
                pop es
                pop bx
                ret
            
    code ends
    end start
            
     
    4.程序入口地址的直接定址表
    例如:传入0、1、2分别调用不同的子程序
    assume cs:code
    code segment
        start:mov ah,2    ;功能参数
            mov al,1    ;颜色参数
            call setscreen
        mov ax,4c00h
        int 21h
        setscreen:    jmp short set
            table    dw sub1,sub2,sub3
            set:    push bx
                    cmp ah,2
                    ja sret
                    mov bl,ah
                    add bx,bx
                    call word ptr table[bx]    
            sret:    pop bx
                    ret
            sub1:    push bx                ;子程序1,用来将屏幕清空
                    push cx
                    push es
                    mov bx,0b800h
                    mov es,bx
                    mov bx,0
                    mov cx,80*25
            sub1s:    mov byte ptr es:[bx],' '
                    add bx,2
                    loop sub1s
                    pop es
                    pop cx
                    pop bx
                    ret
            sub2:    push bx            ;子程序2,切换字体颜色
                    push cx
                    push es
                    mov bx,0b800h
                    mov es,bx
                    mov bx,1
                    mov cx,80*25
            sub2s:    and byte ptr es:[bx],11111000b    ;第0、1、2位控制字体颜色
                    or byte ptr es:[bx],al
                    add bx,2
                    loop sub2s
                    pop es
                    pop cx
                    pop bx
                    ret
            sub3:    push bx
                    push cx
                    push es
                    mov cl,4    ;al参数左移4位,来对应控制颜色的位
                    shl al,cl
                    mov bx,0b800h
                    mov es,bx
                    mov bx,1
                    mov cx,25*80
            sub3s:    and byte ptr es:[bx],10001111b    ;第4、5、6位控制背景色
                    or byte ptr es:[bx],al
                    add bx,2
                    loop sub3s
                    pop es
                    pop cx
                    pop bx
                    ret
    code ends
    end start
     
     
     
  • 相关阅读:
    类和对象系列教材 (一)- 什么是Java中的引用?
    类和对象系列教材 (一)- 什么是Java中的引用?
    数组系列教材 (七)- java.util.Arrays类常用方法
    数组系列教材 (七)- java.util.Arrays类常用方法
    数组系列教材 (七)- java.util.Arrays类常用方法
    数组系列教材 (六)- Java 如何使用二维数组
    数组系列教材 (六)- Java 如何使用二维数组
    [LeetCode] 938. Range Sum of BST
    [LeetCode] 13. Roman to Integer
    [LeetCode] 12. Integer to Roman
  • 原文地址:https://www.cnblogs.com/ShiningArmor/p/11383545.html
Copyright © 2011-2022 走看看