直接定址表

2022-03-27 15:17:27 字數 4102 閱讀 6434

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.直接定址表

在程式設計時常會遇到一些比如用給出的資料通過計算來獲得結果的問題;

例如:將乙個數轉換成十六進製制顯示;

當一次需要轉換的數字很多時,需要多次進行重複的計算轉換;

為了簡化操作,可以將問題轉換為用給出的資料作為查表的依據,通過查表獲得結果;

具體操作是,建一張資料和結果對映表;用資料為條件,計算結果在表中的位置,也就獲取了結果;

這種可以依據資料,直接計算出所要找的元素的位置的表稱為直接定址表;

直接定址表的應用示例**:

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

retcode 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

retsub1:    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

retsub2:    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

retsub3:    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

retcode ends

end start

直接定址表

1 描述了單元長度的標號 後面沒有冒號的標號可以同時描述記憶體位址和單位長度。因為這種標號包含了對單元長度的描述,所以,在指令中,它可以代表乙個段中的記憶體單元。稱為資料標號。2 一般來說,我們不會在 段中定義資料,而是將資料定義到其他段中。注意 1.在後面加有 的位址標號,只能在 段中使用,不能在...

直接定址表

這篇文章中,我們將討論如何有效合理的組織資料,以及相關的程式設計技術.一 描述了單元長度的標號 首先,我們來看乙個簡單的例子 assume cs code code segment a db 1,2,3,4,5,6,7,8,9 b dw 0 start mov si,offset a mov di,...

16 直接定址表

1 前面我們一直在 段使用標號來標記指令 資料 段的起始位置。比如,a db 1,2,3,4,5,6,7,8 b dw 0 程式中,a,b只是標號,它僅僅表示了記憶體單元的位址 但是,我們還可以使用一種標號,這種標號不但標識記憶體單元的位址,還表示了記憶體單元的長度,即表示在此標號的單元,是乙個位元...