A. 匯編語言:SI、DI、BX、BP、SS、DS分別是什麼怎樣根據這些求物理地址
1.匯編語言 SI DI BX BP SS DS 是什麼
SI: 16位寄存器,源變址寄存器
DI: 16為寄存器,目的變址寄存器
BX: 16位寄存器(可分成2個8位寄存器BH,BL),基址寄存器
BP: 16位寄存器,基址指針寄存器
SS : 16位段寄存器,作用是存放當前堆棧段的段地址,一般和SP連用
DS: 16為段寄存器, 作用是存放當前數據段的段地址
2.怎樣根據這些求物理地址
上面的這幾個寄存器跟求物理地址談不上關系.
有個公式: 物理地址 = 基礎地址 + 偏移地址 = CS*10H(基礎地址)+ IP(偏移地址)
CS: 16位段寄存器,存放當前代碼段的段地址
IP: 存放下一條要執行的指令的偏移地址
LZ如有不明白的地方,可追問
B. 匯編語言SI、DI、BX、BP、SS、DS分別是什麼怎樣根據這些求物理地址
1.匯編語言 SI DI BX BP SS DS 是什麼
SI: 16位寄存器,源變址寄存器
DI: 16為寄存器,目的變址寄存器
BX: 16位寄存器(可分成2個8位寄存器BH,BL),基址寄存器
BP: 16位寄存器,基址指針寄存器
SS : 16位段寄存器,作用是存放當前堆棧段的段地址,一般和SP連用
DS: 16為段寄存器, 作用是存放當前數據段的段地址
2.怎樣根據這些求物理地址
上面的這幾個寄存器跟求物理地址談不上關系.
有個公式: 物理地址 = 基礎地址 + 偏移地址 = CS*10H(基礎地址)+ IP(偏移地址)
CS: 16位段寄存器,存放當前代碼段的段地址
IP: 存放下一條要執行的指令的偏移地址
LZ如有不明白的地方,可追問
C. 匯編語言 mov ax, [ bp ] 在求物理地址時 為什麼使用ss為段地址而不實用ds為段地址
1)MOVAX,ES:[1000H]AX=9ABCH地址:31000H演算法:ES*10H+1000H聲明的段寄存器ES2)MOVAX,[BX]AX=3412H地址:21000H演算法:DS*10H+BX默認段寄存器DS3)MOVAX,[BX][SI]AX=?地址:21001H演算法:DS*10H+BX+SI默認段寄存器DS這道題是不是你哪裡敲錯了,你題中沒有這個21001H地址4)MOVAX,[BP+DI]AX=9A78H地址:41002H演算法:SS*10H+BP+DI默認段寄存器SS方括弧裡面代表地址,比如movax,[bx]就等於movax,[1000h],冒號代表段前綴,冒號前面的是段寄存器,將以指明的段寄存器定址,段寄存器*10H+後面的地址即是物理地址,如果沒有指明段前綴,將以默認的段寄存器定址,BX,SI,DI這3個寄存器默認的段寄存器是DS,BP的默認段寄存器是SS
D. 匯編語言 SI DI BX BP SS DS 是什麼 怎樣根據這些求物理地址
SI、DI、BX、BP是8086CPU可用來作指針使用的寄存器,一般用來表示一個偏移量,具體的和定址方式有關。
SS、DS是段地址寄存器。
由於8086CPU是16的,而其存儲容量可達1MB,也就是20位的定址空間,因此編程時用兩個16位的地址來表示,即 段地址:偏移地址,它和實際地址,也就是物理地址的關系是:
物理地址=段地址×16+偏移地址
對於上面的寄存器,當作地址使用時,根據定址方式不同,有一種默認關系,只要指令中出現BP作地址的,則其段地址為SS,否則就為DS。當然還有段前綴一說,這要看實際情況來定了。
比如:
MOV AX,[BX];則其物理地址=DS×16+BX
MOV AX,[BP];則其物理地址=SS×16+BP
MOV AX,[BX][SI] ;則其物理地址=DS×16+(BX+SI)
MOV AX,[BP][SI];則其物理地址=SS×16+(BP+SI)
E. ds,ss,fss,怎麼算
ds,cs,ss都是匯編中的段寄存器而ip狀態與控制寄存器,sp為索引寄存器,cs與ip搭配使用,ss與sp搭配使用;雖然ds,cs,ss都是段寄存器但是他們的作用卻大不相同,
cs:代碼段寄存器ds:數據段寄存器ss:堆棧段寄存器es:擴展段寄存器fs:標志段寄存器gs:全局段寄存器
F. 匯編語言中 cs、ds、ss的區別是什麼
CS:代碼段寄存器;DS:數據段寄存器;SS:堆棧段寄存器;當一個程序要執行時,就要決定程序代碼、數據和堆棧各要用到內存的哪些位置,通過設定段寄存器 CS,DS,SS 來指向這些起始位置。通常是將DS固定,而根據需要修改CS。cs 代碼段地址,聯合ip作為cpu指向當前正在執行的那條指令所使用,你一般不能隨意修改它ss 堆棧段地址 聯合sp定義一個堆棧,一旦你確定了堆棧地址,ss也不能隨便改變了ds 數據段地址,定義一個數據段如果你是新手的話,有需要的時候,你可以用ds和es,隨著更加深入的學習你會了解具體怎麼用的。
G. 匯編語言中cs.ds.es.ss都怎麼用啊
想知道他們怎麼用,就必須了解他們的用途,他們和其他寄存器如何合作,寄存器定址和存儲器定址如何完成?單說這幾個段寄存器,不涉及其他寄存器,是不能真正了解掌握他們的。學習需要循序漸進,「莫在浮沙築高台」
---------------
寄存器是中央處理器內的組成部份。寄存器是有限存貯容量的高速存貯部件,它們可用來暫存指令、數據和位址。在中央處理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序計數器(PC)。在中央處理器的算術及邏輯部件中,包含的寄存器有累加器(ACC)。
寄存器是內存階層中的最頂端,也是系統獲得操作資料的最快速途徑。寄存器通常都是以他們可以保存的位元數量來估量,舉例來說,一個 「8 位元寄存器」或 「32 位元寄存器」。寄存器現在都以寄存器檔案的方式來實作,但是他們也可能使用單獨的正反器、高速的核心內存、薄膜內存以及在數種機器上的其他方式來實作出來。
寄存器通常都用來意指由一個指令之輸出或輸入可以直接索引到的暫存器群組。更適當的是稱他們為 「架構寄存器」。
例如,x86 指令及定義八個 32 位元寄存器的集合,但一個實作 x86 指令集的 CPU 可以包含比八個更多的寄存器。
寄存器是CPU內部的元件,寄存器擁有非常高的讀寫速度,所以在寄存器之間的數據傳送非常快。
[編輯本段]寄存器用途
1.可將寄存器內的數據執行算術及邏輯運算;
2.存於寄存器內的地址可用來指向內存的某個位置,即定址;
3.可以用來讀寫數據到電腦的周邊設備。
[編輯本段]數據寄存器
8086 有14個16位寄存器,這14個寄存器按其用途可分為(1)通用寄存器、(2)指令指針、(3)標志寄存器和(4)段寄存器等4類。
(1)通用寄存器有8個, 又可以分成2組,一組是數據寄存器(4個),另一組是指針寄存器及變址寄存器(4個).
數據寄存器分為:
AH&AL=AX(accumulator):累加寄存器,常用於運算;在乘除等指令中指定用來存放操作數,另外,所有的I/O指令都使用這一寄存器與外界設備傳送數據.
BH&BL=BX(base):基址寄存器,常用於地址索引;
CH&CL=CX(count):計數寄存器,常用於計數;常用於保存計算值,如在移位指令,循環(loop)和串處理指令中用作隱含的計數器.
DH&DL=DX(data):數據寄存器,常用於數據傳遞。
他們的特點是,這4個16位的寄存器可以分為高8位: AH, BH, CH, DH.以及低八位:AL,BL,CL,DL。這2組8位寄存器可以分別定址,並單獨使用。
另一組是指針寄存器和變址寄存器,包括:
SP(Stack Pointer):堆棧指針,與SS配合使用,可指向目前的堆棧位置;
BP(Base Pointer):基址指針寄存器,可用作SS的一個相對基址位置;
SI(Source Index):源變址寄存器可用來存放相對於DS段之源變址指針;
DI(Destination Index):目的變址寄存器,可用來存放相對於 ES 段之目的變址指針。
這4個16位寄存器只能按16位進行存取操作,主要用來形成操作數的地址,用於堆棧操作和變址運算中計算操作數的有效地址。
(2) 指令指針IP(Instruction Pointer)
指令指針IP是一個16位專用寄存器,它指向當前需要取出的指令位元組,當BIU從內存中取出一個指令位元組後,IP就自動加1,指向下一個指令位元組。注意,IP指向的是指令地址的段內地址偏移量,又稱偏移地址(Offset Address)或有效地址(EA,Effective Address)。
(3)標志寄存器FR(Flag Register)
8086有一個18位的標志寄存器FR,在FR中有意義的有9位,其中6位是狀態位,3位是控制位。
OF: 溢出標志位OF用於反映有符號數加減運算所得結果是否溢出。如果運算結果超過當前運算位數所能表示的范圍,則稱為溢出,OF的值被置為1,否則,OF的值被清為0。
DF:方向標志DF位用來決定在串操作指令執行時有關指針寄存器發生調整的方向。
IF:中斷允許標志IF位用來決定CPU是否響應CPU外部的可屏蔽中斷發出的中斷請求。但不管該標志為何值,CPU都必須響應CPU外部的不可屏蔽中斷所發出的中斷請求,以及CPU內部產生的中斷請求。具體規定如下:
(1)、當IF=1時,CPU可以響應CPU外部的可屏蔽中斷發出的中斷請求;
(2)、當IF=0時,CPU不響應CPU外部的可屏蔽中斷發出的中斷請求。
TF:跟蹤標志TF。該標志可用於程序調試。TF標志沒有專門的指令來設置或清楚。
(1)如果TF=1,則CPU處於單步執行指令的工作方式,此時每執行完一條指令,就顯示CPU內各個寄存器的當前值及CPU將要執行的下一條指令。
(2)如果TF=0,則處於連續工作模式。
SF:符號標志SF用來反映運算結果的符號位,它與運算結果的最高位相同。在微機系統中,有符號數採用補碼表示法,所以,SF也就反映運算結果的正負號。運算結果為正數時,SF的值為0,否則其值為1。
ZF: 零標志ZF用來反映運算結果是否為0。如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標志位。
AF:下列情況下,輔助進位標志AF的值被置為1,否則其值為0:
(1)、在字操作時,發生低位元組向高位元組進位或借位時;
(2)、在位元組操作時,發生低4位向高4位進位或借位時。
PF:奇偶標志PF用於反映運算結果中「1」的個數的奇偶性。如果「1」的個數為偶數,則PF的值為1,否則其值為0。
CF:進位標志CF主要用來反映運算是否產生進位或借位。如果運算結果的最高位產生了一個進位或借位,那麼,其值為1,否則其值為0。)
4)段寄存器(Segment Register)
為了運用所有的內存空間,8086設定了四個段寄存器,專門用來保存段地址:
CS(Code Segment):代碼段寄存器;
DS(Data Segment):數據段寄存器;
SS(Stack Segment):堆棧段寄存器;
ES(Extra Segment):附加段寄存器。
當一個程序要執行時,就要決定程序代碼、數據和堆棧各要用到內存的哪些位置,通過設定段寄存器 CS,DS,SS 來指向這些起始位置。通常是將DS固定,而根據需要修改CS。所以,程序可以在可定址空間小於64K的情況下被寫成任意大小。 所以,程序和其數據組合起來的大小,限制在DS 所指的64K內,這就是COM文件不得大於64K的原因。8086以內存做為戰場,用寄存器做為軍事基地,以加速工作。
以上是8086寄存器的整體概況, 自80386開始,PC進入32bit時代,其定址方式,寄存器大小,功能等都發生了變化。
=============================以下是80386的寄存器的一些資料======================================
寄存器都是32-bits寬。
A、通用寄存器
下面介紹通用寄存器及其習慣用法。顧名思義,通用寄存器是那些你可以根據自己的意願使用的寄存器,修改他們的值通常不會對計算機的運行造成很大的影響。通用寄存器最多的用途是計算。
EAX:通用寄存器。相對其他寄存器,在進行運算方面比較常用。在保護模式中,也可以作為內存偏移指針(此時,DS作為段 寄存器或選擇器)
EBX:通用寄存器。通常作為內存偏移指針使用(相對於EAX、ECX、EDX),DS是默認的段寄存器或選擇器。在保護模式中,同樣可以起這個作用。
ECX:通用寄存器。通常用於特定指令的計數。在保護模式中,也可以作為內存偏移指針(此時,DS作為 寄存器或段選擇器)。
EDX:通用寄存器。在某些運算中作為EAX的溢出寄存器(例如乘、除)。在保護模式中,也可以作為內存偏移指針(此時,DS作為段 寄存器或選擇器)。
同AX分為AH&AL一樣,上述寄存器包括對應的16-bit分組和8-bit分組。
B、用作內存指針的特殊寄存器
ESI:通常在內存操作指令中作為「源地址指針」使用。當然,ESI可以被裝入任意的數值,但通常沒有人把它當作通用寄存器來用。DS是默認段寄存器或選擇器。
EDI:通常在內存操作指令中作為「目的地址指針」使用。當然,EDI也可以被裝入任意的數值,但通常沒有人把它當作通用寄存器來用。DS是默認段寄存器或選擇器。
EBP:這也是一個作為指針的寄存器。通常,它被高級語言編譯器用以建造『堆棧幀'來保存函數或過程的局部變數,不過,還是那句話,你可以在其中保存你希望的任何數據。SS是它的默認段寄存器或選擇器。
注意,這三個寄存器沒有對應的8-bit分組。換言之,你可以通過SI、DI、BP作為別名訪問他們的低16位,卻沒有辦法直接訪問他們的低8位。
C、段選擇器:
實模式下的段寄存器到保護模式下搖身一變就成了選擇器。不同的是,實模式下的「段寄存器」是16-bit的,而保護模式下的選擇器是32-bit的。
CS 代碼段,或代碼選擇器。同IP寄存器(稍後介紹)一同指向當前正在執行的那個地址。處理器執行時從這個寄存器指向的段(實模式)或內存(保護模式)中獲取指令。除了跳轉或其他分支指令之外,你無法修改這個寄存器的內容。
DS 數據段,或數據選擇器。這個寄存器的低16 bit連同ESI一同指向的指令將要處理的內存。同時,所有的內存操作指令 默認情況下都用它指定操作段(實模式)或內存(作為選擇器,在保護模式。這個寄存器可以被裝入任意數值,然而在這么做的時候需要小心一些。方法是,首先把數據送給AX,然後再把它從AX傳送給DS(當然,也可以通過堆棧來做).
ES 附加段,或附加選擇器。這個寄存器的低16 bit連同EDI一同指向的指令將要處理的內存。同樣的,這個寄存器可以被裝入任意數值,方法和DS類似。
FS F段或F選擇器(推測F可能是Free?)。可以用這個寄存器作為默認段寄存器或選擇器的一個替代品。它可以被裝入任何數值,方法和DS類似。
GS G段或G選擇器(G的意義和F一樣,沒有在Intel的文檔中解釋)。它和FS幾乎完全一樣。
SS 堆棧段或堆棧選擇器。這個寄存器的低16 bit連同ESP一同指向下一次堆棧操作(push和pop)所要使用的堆棧地址。這個寄存器也可以被裝入任意數值,你可以通過入棧和出棧操作來給他賦值,不過由於堆棧對於很多操作有很重要的意義,因此,不正確的修改有可能造成對堆棧的破壞。
* 注意 一定不要在初學匯編的階段把這些寄存器弄混。他們非常重要,而一旦你掌握了他們,你就可以對他們做任意的操作了。段寄存器,或選擇器,在沒有指定的情況下都是使用默認的那個。這句話在現在看來可能有點稀里糊塗,不過你很快就會在後面知道如何去做。
指令指針寄存器:
EIP 這個寄存器非常的重要。這是一個32位寬的寄存器 ,同CS一同指向即將執行的那條指令的地址。不能夠直接修改這個寄存器的值,修改它的唯一方法是跳轉或分支指令。(CS是默認的段或選擇器)
上面是最基本的寄存器。下面是一些其他的寄存器,你甚至可能沒有聽說過它們。(都是32位寬):
CR0, CR2, CR3(控制寄存器)。舉一個例子,CR0的作用是切換實模式和保護模式。
還有其他一些寄存器,D0, D1, D2, D3, D6和D7(調試寄存器)。他們可以作為調試器的硬體支持來設置條件斷點。
TR3, TR4, TR5, TR6 和 TR? 寄存器(測試寄存器)用於某些條件測試。
H. 8086/8088求物理地址時那些CS,DS,SS,IP什麼的有什麼用要怎麼求,求教!
...
求物理地址時基本上恩他們沒太大關系吧。。
他們只是存放數據的寄存器(相當與變數),比如把1234放到cs里,以後寫cs就是1234這個東東。
然後後來就有人規定一些東西一般只放特定含義的東西。
怎麼說呢,就像2l說的cs是放段基址的,在8086里一個20位的地址是由2個16位的地址構成的,所以要兩個16位的寄存器才能表示一個地址,cs里的內容+另一個特定的寄存器里的內容構成一個特定的地址而且這個地址是程序的......ds+另一個構成...數據地址的..ss一般用於堆棧的。比較復雜,還是看看書把,和定址有關。當訪問不同的東西(程序,數據,堆棧)時會配上不同的(cs,ds,ss)段寄存器。
至於物理地址的求法:
一個8086里地址是20位的它由兩個16位的數構成,一個叫段地址,一個叫偏移地址,
實際物理地址=段地址*10H+偏移地址,
10H是十六進制的10,(一般地址都是給出16位的形式。所以一般就是段地址後面加個0再與偏移地址相加。在程序中依據訪問不同內容段地址在cs,ds,ss中選(特殊的定址除外),例如用ip做偏移地址時,會調用cs作為段地址,實際物理地址就是cs*10h+ip,...)
I. 源操作數的物理地址是es ds ss 怎麼判斷
這圖太難看了
J. 匯編語言中 cs, ds,ss 的區別
最近想初步了解一下匯編的內容,在網上搜了搜,發現一篇寫得很不錯的文章,特地轉過來留存。寫得淺顯易懂,而且加入了很多個人的見解,比書上寫的好懂多了。比較欽佩作者,可惜找了半天沒有找到這篇文章的原作者是誰。轉載地址: http://www.zxbc.cn/html/20070611/22772.html 學習匯編前你應該知道的知識
1、匯編需要什麼工具和程序,到哪裡下載?
目前階段,匯編程序僅需要兩個程序就夠了。masm.exe,link.exe。 前者是編譯程序,後者是鏈接程序。另外,為了驗證和調試程序,還需要一個程序debug.exe,該程序由windows本身就提供。
將二者下載後,放到某一個目錄中(任意目錄都可以),考慮到很多命令需要通過鍵盤敲入,所以建議你不要把文件放入到長文件名目錄、中文目錄或很深的目錄中。比如你可以建一個「D:\Masm」目錄,並建議此後的程序都放這個目錄,此後稱這個目錄為匯編目錄。 2、學習匯編需要有哪些編程方面的知識?
沒有任何編程方面的知識,學習此語言等於緣木求魚,所以請放棄學習的想法。一般來說至少要知道如下幾點:
*)程序的運行邏輯結構有順序(按語句依次執行)、分支結構(IF...THEN...ELSE...),循環結構(FOR...NEXT)三種結構。
*)知道什麼是子程序,什麼是調用。
*)匯編程序員的視角。不同編程視角編程要求是不一樣的。比如刪除文件:
>>用戶的視角是找到「刪除」按鈕或菜單,然後單擊一下即可。
>>高級程序員的視角是知道刪除的文件,並發出刪除命令。這些通過API實現。
>>匯編程員的視角是得到要刪除的文件名,找到該文件所在位置,通過調用刪除「中斷命令」進行刪除。
>>操作系統開發人員的視角則是接到刪除命令後,先找到系統根目錄區,由根目錄區的鏈接依次找到子目錄區,直到找到要刪除的文件,然後按照操作系統刪除文件的規則對該文件名進行修改。比如DOS,只把第一個字元改成"?"。 按程序語句等價的角度看,一行VB的列印語句,用匯編實現大約需要一百二十多行。知道匯編語言的視角後就要知道,前面的道路是坎坷的,沒有耐心是不行的。想通過幾分鍾幾行程序就完成很復雜的操作不是件容易的事。 3、學匯編有什麼用?
匯編產生於DOS時代或更早,而現在是Windows時代,所以可能 遺憾地說:盡管還有批牛人在用匯編開發核心級程序,但我們幾乎沒什麼用,除了必要時間能拿來分析一兩個程序的部分代碼之外,別的也就沒干什麼用了。並且並不是所有的匯編命令都能在windows下使用。而泛泛地追求「時髦」而學本語言,最後的結果是損了夫人又折兵。所以學之前你要考慮好。我勸那些為了當「黑客」而學匯編的人就此止步。
第零講 預備知識 1、一個匯編程序的編譯過程是怎麼樣的?
1)首先你需要找一個編輯器,編輯器用任何「純文本」編輯器都可以。比如記事本。編好以後保存到匯編目錄中。擴展名為asm,比如myfirst.asm。但這里建議你找一個能顯示出當前行的編譯器。這樣出錯後排錯很容易。
2)然後在DOS下進入D:\Masm目錄中,輸入「masm myfirst.asm",如果有錯系統會提示出錯的行位置和出錯原因。 3)然後再輸入「link myfirst.obj」,即可看到當前目錄下有一個myfirst.exe程序。 2、宏匯編和匯編有什麼區別嗎?
二者的區別在於前者提供宏,後者不提供。後者已找不到了,所以你可以認為二者沒有區別。 3、機器語言、匯編語言、高級語言的關系
最早的計算機採用機器語言,這種語言直接用二進制數表示,通過直接輸入二進制數,插拔電路板等實現,這種「編程」很容易出錯,每個命令都是通過查命令表實現,既然是通過「查表」實現的,那當然也可以讓計算機來代替人查表實現了。於是就產生了匯編語言,所以不管別人怎麼定義機、匯語言,我就認為,二者是等價。後來人們發現,用匯編語言編某一功能的時候,連續一段代碼都是相同或相似,於是就考慮用一句語言來代替這一段匯編語言,於是就產生了高級語言。因此,所有高級語言都能轉化成匯編語言,而所以匯編語言又可轉化成機器語言。反之,所有機器語言可以轉成匯編語言(因為二者等價)。但並不是所以匯編語言都能轉成高級語言。 4、計算機的組成
通常都把計算機定義成五部分:運算器、控制器、存儲器、輸入系統、輸出系統。
為了簡單起見,我們如此理解:運算器+控制器=CPU。存儲器=內存(暫不包括外存,也不包括CACHE)。輸入系統=鍵盤(不包括滑鼠),輸出系統=顯示器(不包括列印機,繪圖儀)。 5、寄存器和內存的區別
寄存器在CPU中。內存在內存條中。前者的速度比後者快100倍左右。後面的程序要求每條指定要麼沒有內存數據,要麼在有一個寄存器的參與下有一個內存數據。(也就是說,不存在只訪問內存的指令)。 6、匯編語言的計數
與生活中的計數不一樣,匯編中的計數是從0開始的。比如16個計數,則是從0~15,而不是生活中的1~16。這一點看起來簡單,真運算起來就不是件容易的事了,不信等著瞧。 7、進制問題
又與生活中不一樣的地方是進制。切記下面的常識:
*)計算機內部存儲都用二進制。
*)我們的匯編源程序默認都用十進制。(除非你指明類型)
*)我們用的調試程序debug默認的都是十六進制。(無法指明其他類型)
其中十六進制的十六個個位數依次是:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F。 8、進制轉換
一個比較簡單的方法是查表法。
十進制 十六進制 二進制
0 0 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5 5 0101
6 6 0110 7 7 0111
8 8 1000
9 9 1001
10 A 1010
11 B 1011
12 C 1100
13 D 1101
14 E 1110
15 F 1111
好了,結合6,7,8三條。大家來算一個「題」。某一組數據顯示時,每個數據佔了四個位置,每行共十六個。問:十六進制的13位置在哪裡(第幾行,第幾列)。
格式如下:m m m m n n n n o o o o p p p p '註:之所以沒用ABC是怕與上面十六進制弄混。
r r r r s s s s t t t t u u u u
第一講 基礎知識
1、訪問內存
程序在內存中,訪問內存是幾乎每一程序都要進行的操作,計算機對內存編址是線性的,也就是說是一維的,比如256M的內存,地址就應該是從0~(256M-1),這個地址稱為物理地址或絕對地址。
1.1 地址表示
但從匯編程序員的角度看,內存卻是二維的,要說明一個地址,需要給出兩個值,就象你在平面上指定一點需要說出(X,Y)坐標一樣,匯編程序員的內存視角也需要兩個「坐標」,前一個稱為段地址(Segment),後一個稱為偏移地址(Offset),該地址稱為邏輯地址。
比如「1234:3DF5」就是一個地址。「1F3F:」不是一個地址,因為他只有段地址,沒有偏移地址。注意此後的地址都用十六進製表示。
1.2 地址計算
前面提到,計算機編址是一維的,匯編程序員是二維的,那麼二者怎麼換算呢?由後者到前者的換算方法是,「段地址串」後面加個「0」,然後再加上偏移地址。
比如「1234:3DF5」(十六進制的加減運算參見相關資料)
12340 --串後加了一個0
3DF5
-----
16135 --注意此串仍然是十六進制。
所以,匯編程序員眼中的地址「1234:3DF5」就是物理地址(計算機編址):16135。
知道了由後者向前者的轉換,那麼由前者向後者的轉換呢?
「不知道」,為什麼不知道,繼續往下看。
1.3 到底哪個地址對 知道了1.2的地址演算法後,我又發現一個問題:
「1000:6135」的物理地址是多少呢? 10000+6135=16135。
「1001:6125」的物理地址呢? 10010+6125=16135。
......
那麼到底哪個對呢?問題的回答是這樣的:假設我現在讓你按一下「L」鍵,我可以告訴你如下幾種方法中的一種或幾種。1 請按一下「L」鍵; 2請按一下鍵盤上第四行第十個鍵;3 請按一下第十列中的第四個鍵;4 請按一下「K」右邊的鍵;5 按標准指法單擊一下右手無名指。 舉上面的例子也就是說,同一個地址有很多種表示方式,具體用哪一種,要看實際使用時的情況。但無論用哪種方式,只要能達到目的即可。(實際中該問題一般不會受此問題困擾,但初學時突然想不通)。
1.4 有多少內存可以訪問
無論是段地址還是偏移地址都是四位十六進制(如果不夠四位,前面補0)。也就是說:總共可以訪問的地址說是:0000:0000~FFFF:FFFF。 總共FFFF0+FFFF+1=10FFF0個地址。也就是不到1M的空間。
記住如下結論:
*) 不管你實際內存有多少,目前我們只能訪問不到1M的空間。
*) 而實際上連這1M也用不完。其中上端的384K的址只能讀不能寫,只能讀,一般稱為ROM。
*) 低端的640K可以讀寫。但這640K的低端100多K也不能隨便寫,因此DOS系統使用該區。
*) 原來1024M的內存,匯編程序只能使用其中400多K。這段內存的容易相當於一個普通文檔的大小。不過這就足夠了。