2012-01-03 151 views
0

我學習彙編語言編程,我遇到了與註冊的一些問題。比如我碰到這樣的:彙編語言註冊

mov ax, 3000 
mov ds, ax 
mov si, 200 
mov ax, [si] 
add si, 2 
add ax, [si] 
add si, 2 
mov [si], ax 
mov ax, 4c00 
int 21 

該代碼使得2個內存段從3000總和:200和3000:202,並把對3000結果:202,我不明白DS之間的連接因爲我無法解釋我們爲什麼要這樣做,斧頭?我一般不明白寄存器之間的連接......我知道他們主張,但...我不知道有些幫助將是非常有用的感謝

回答

1

Ds在數據段寄存器。地址如您所述,通過組合ds寄存器和si寄存器組成。在舊八十六分之八千零八十八天,或許你仍然在這種情況下,計算出你的地址(DS < < 4)+ SI。 mov到ax然後是ds,因爲可能會限制你可以/不能立即執行的動作。也許你不能做mov ds,3000,在任何情況下,ax都被用作中間寄存器,根本沒有連接,只能讓3000進入ds寄存器。所以如果ds = 3000且si = 200,那麼地址是,我假設(3000 < < 4)+200。

ds和SI之間的連接是隱含的。查看來自intel的程序員參考手冊當使用SI或DI時,DS段是默認值。 CS:ES:SS是SI的交替(但不是DI),您需要在指令/程序集中指定替代段以使用其他段中的一個。您如何指定備用段取決於彙編程序所期望的語法。

0

簡而言之,

你不能直接給段寄存器賦值立即數。這就是爲什麼你使用通用註冊表來爲你工作。

mov ds, ax 

關於DS和SI,您有一些假設DS:SI正常工作的說明,但在此情況並非如此。 DS是您的默認數據段,因此它只是假設DS:offset; SI在你的情況下是你的抵消。您可以將SI更改爲任何其他16位寄存器,例如CX,它可以同樣工作。進行測試和反饋我:P

3

DS是數據段寄存器 - 象所有的段寄存器,它的值乘以16表示的存儲器中的64K塊的基地址。

當執行指令,存儲器地址由以由一個段寄存器表示的基地址(默認情況下,DS寄存器用於數據)並添加一個常數或一個寄存器中指定的偏移值來計算。

所以,mov ax, [si]相當於mov ax, [ds:si]這(與你的寄存器值)代表mov ax, [3000:200]。在內部,處理器將計算(3000 * 16)+200的絕對內存地址,並將該內存位置的數據複製到ax。在添加和保存結果時,對存儲器訪問使用類似的過程。

你無法做的原因mov ds, 3000只是因爲英特爾決定不支持將常量值移入段寄存器 - 沒有編碼指令。相反,您必須通過另一個寄存器傳送值(在您的代碼中使用ax)。您的(原始)描述不太正確 - 代碼確實會在[3000:200]和[3000:202]處添加值,但結果將存儲到[3000:204](不是[3000] :202])。不要忘記:像DS(和CS,ES,FS和GS)這樣的段寄存器中存儲的值不直接指定基地址 - 它們必須始終乘以16才能得到真實的基地址。