這篇文章中,我們將討論如何有效合理的組織資料,以及相關的程式設計技術.
一、描述了單元長度的標號
首先,我們來看乙個簡單的例子:
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,offset b
mov cx,9
s: mov al,cs:[si]
mov ah,0
add cs:[di],ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
不難看出上面程式是將a標號處的9個資料累加,結果存在b標號中的字中.程式中,code,a,b,start,s都是標號,這些標號僅僅表示了記憶體單元的位址.但是,我們還可以使用一種標號,這種標號不但表示記憶體單元的位址,還表示了記憶體單元的長度,即表示在此標號處的單元,是乙個位元組單元,還是字單元,還是雙字單元,上面程式還可以這樣寫:
assume cs:code
code segment
a db 1,2,3,4,5,6,7,8,9
b dw 0
start:
mov si,0
mov cx,9
s:
mov al,a[si]
mov ah,0
add b,ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
在code段中使用的a、b後面沒有「:」,它們是同事描述記憶體位址和單元長度的標號.標號a,描述了位址code:0,和從這個位址開始,以後的記憶體單元位址都是位元組單元;而標號b描述了位址code:9,和從這個位址開始,以後的記憶體單元都是字單元.
因為這種標號包含了對單元長度的描述,所以在指令中,它可以代表乙個段中的記憶體單元,比如對於程式中的「b dw 0」
在這些指令中,標號b代表了乙個記憶體單元,位址為code:8,長度為兩個位元組
下面指令會引起編譯錯誤:
mov al,b
對於程式中」a db 1,2,3,4,5,6,7,8,9″
可見這種包含單元長度的標號,可以使我們以簡潔的形式訪問記憶體中的資料.
下面程式將code段中a處的8個資料累加,結果存在b處的雙字中:
assume cs:code
code segment
a dw 1,2,3,4,5,6,7,8
b dd 0
start:
mov si,0
mov cx,8
s:
mov ax,a[si]
add word ptr b[0],ax
adc word ptr b[2],0
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start
二、在其它段中使用資料標號
一般來說,我們不在**段中定義資料,而是將資料定義到其它段中.在其它段中我們也可以使用資料標號來描述儲存資料的單元的位址和長度.注意:在後面加有」:」的位址標號,只能在**段中使用,不能在其它段中使用.
下面面程式是將a標號處的8個資料累加,結果存在b標號中的字中:
assume cs:codeassume ds:datadata segment
a db 1,2,3,4,5,6,7,8
b dw 0
data ends
code segment
start:mov ax,data
mov ds,axmov si,0
mov cx,8
mov ah,0
s:
mov al,a[si]
add b,ax
add si,1
loop s
mov ax,4c00h
int 21h
code ends
end start
注意,如果想在**段中直接用資料標號訪問資料,則需要用偽指令assume將標號所在的段和乙個段暫存器聯絡起來.否則編譯器在編譯的時候,無法確定標號的段位址在哪乙個暫存器中.當然這種聯絡是編譯器需要的,並不是說編譯器會自動給我們設定ds段的值.
我們可以將標號作為資料來定義:
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dw a,b
data ends
相當於:
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dw offset a,offset b
data ends
再比如:
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dd a,b
data ends
相當於:
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
c dw offset a,seg a,offset b,seg b
data ends
三、使用直接定址表輸出16進製制assume cs:code
assume ds:data
data segment
table db '0123456789abcdef'
data ends
code segment
start:
mov ax,data
mov ds,ax
mov cx,4
mov ax,0fe1ah
s: mov bx,0
mov bl,ah
and bl,0f0h;
shr bl,1
shr bl,1
shr bl,1
shr bl,1
push ax
mov dl,table[bx]
mov ah,2
int 21h
pop ax
shl ax,1
shl ax,1
shl ax,1
shl ax,1
loop s
mov ax,4c00h
int 21h
code ends
end start
可以看出,這個就像高階語言的陣列 直接定址表
1 描述了單元長度的標號 後面沒有冒號的標號可以同時描述記憶體位址和單位長度。因為這種標號包含了對單元長度的描述,所以,在指令中,它可以代表乙個段中的記憶體單元。稱為資料標號。2 一般來說,我們不會在 段中定義資料,而是將資料定義到其他段中。注意 1.在後面加有 的位址標號,只能在 段中使用,不能在...
直接定址表
1.資料標號 關於標號 在彙編 中,可以用標號表示該段 的記憶體位址 標號格式為,標號名加冒號 start 例如 下面的 中 start 就是標號 start mov ax,0 mov bx,ax 關於資料標號 普通的標號只能表示記憶體位址 資料標號即可表示記憶體位址,也可表示記憶體單元的長度 使用...
16 直接定址表
1 前面我們一直在 段使用標號來標記指令 資料 段的起始位置。比如,a db 1,2,3,4,5,6,7,8 b dw 0 程式中,a,b只是標號,它僅僅表示了記憶體單元的位址 但是,我們還可以使用一種標號,這種標號不但標識記憶體單元的位址,還表示了記憶體單元的長度,即表示在此標號的單元,是乙個位元...