2011-09-08 76 views
6

les組裝指令的目的是什麼?Les指令的目的是什麼?

爲什麼我們需要加載es註冊?書中給出了下面的例子:

les bx, p   ; Load p into ES:BX 
mov es:[bx], al  ; Store away AL 

爲什麼我們需要加載在這種情況下esbx?我們爲什麼使用es:[bx]?如果p指向內存100h,則不是esbx 100h = 200h(bx+es)?

回答

9

它太糟糕了,你正在學習一個凌亂的架構微處理器的彙編程序。您會遇到混淆的概念,例如LES指令。

傳統的微處理器有足夠大的寄存器來包含完整的存儲器地址。您可以簡單地將一個內存位置的地址加載到一個寄存器中,然後通過該寄存器訪問該位置(通常是附帶索引的位置)。有些機器(特別是Intel 286似乎是你正在編程的),只有16位寄存器,但可以處理1mB的內存。在這種情況下,寄存器沒有足夠的位:您需要20位,但寄存器只有16位。

解決方案是讓第二個寄存器包含缺失的位。一個簡單的方案是要求2個寄存器,其中一個具有較低的16位,其中一個具有較高的16位,以產生32位地址。然後引用兩個寄存器的指令是有意義的:你需要得到一個完整的內存地址。

Intel選擇了一種混亂的方案:索引寄存器(bx在你的情況下)包含低16位,而另一個寄存器(稱爲ES)包含16位左移4位,並添加到索引寄存器,得到結果地址。 ES被稱爲「段」寄存器,但除非您閱讀大約1968年的Multics operating system,否則這將毫無意義。

[段和段寄存器在完全實現Multics方式時確實是一個有趣的想法。如果您不知道這是什麼,並且您對計算機和/或信息架構有興趣,請查找關於Multics的Elliot Organick書,並閱讀其封面。你會對我們在60年代後期所發生的事情感到沮喪,並且似乎已經在50年的「進步」中失去了。]

在x86中剩下的想法幾乎是一個笑話,至少是它的方式用於「現代」操作系統。你並不在乎;當一些硬件設計師給你提供一臺機器時,你必須像現在一樣使用它。

對於Intel 286,您只需加載段寄存器和索引寄存器即可獲取完整地址。每臺機器必須引用一個索引寄存器和一個段寄存器,以形成一個完整的地址。對於英特爾286,有4個這樣的分段重定向器:DS,SS,ES和CS。每種指令類型都明確指定一個索引寄存器,並隱式選擇4個段寄存器中的一個,除非你提供了一個明確的覆蓋來說明使用哪一個。除非另有說明,JMP說明使用CS。除非另有說明,MOV說明使用DS。 PUSH指令使用SS,除非你另有說明(在這種情況下,你最好不要)。 ES是「額外」部分;只能通過在指令中明確引用它來使用它(除了塊移動[MOVB}指令,它隱式使用DS和ES)。

希望有所幫助。

最好使用更先進的微處理器,其中段寄存器愚蠢不是問題。

+0

您的回答*主要*正確。但是,所有現代x86處理器都使用段寄存器。即使在大多數情況下都是平坦的64位模式下,你仍然有GS和FS不平坦。如果有的話,這個細分市場的惡性現在比你在文章中描述的要複雜得多。 –

+2

是的,他們這樣做,但OP不需要聽到這種併發症。目前的利用率(x64)也不是真實分段寄存器最糟糕的痕跡。這樣的恥辱,請參閱Multics參考。 (安迪格羅夫在80年代中期在一次談話中站了起來,炸了他的堆棧......英特爾設計了386段寄存器來真正實現Multics,而且他被Unix的微軟忽視了,我們應該接受我們所接受的)。 –

+2

非常感謝! 「*您需要20位,但寄存器只有16位。*「我完全忘記了我正在使用16位CPU! –

3

p指向一個帶段和偏移量部分的32位FAR指針(與只有偏移量部分的NEAR指針相反)。 LES將加載段:抵消到ES:BX

否則,您將不得不使用三條指令。 一個用於加載BX,另兩個用於加載ES(段寄存器不能直接從存儲器加載,但必須加載到通用寄存器,然後加載到段寄存器中)。

哦,是的,是的,Wallyk提到保護模式有一個好處(雖然這是旁邊的問題點)。 這裏,ES將被解釋爲選擇器,而不是實際的片段。

此上下文中的段(地址)是物理地址的一部分:
將段向左移動4位(即將其乘以2^4 = 16),並添加偏移量以獲取物理來自segment:offset的地址。相反,選擇器是指向所謂描述符表中的條目的指針(即,選擇器指向描述符)並且用於保護模式。 描述符表(例如GDT)可以包含關於存儲器塊的信息條目,包括關於物理存儲器地址,塊大小,訪問權限等的信息(還有一些稍微其他用途)。

5

8086段寄存器csdses,和ss是原始機制,通過該16位寄存器可以尋址超過64K的存儲器。在8086/8088中,有20位地址(1024 K)被生成。後續版本的x86處理器增加了新的方案來解決更多問題,但是從一對16位值生成20+位地址是基本原因。

在所謂的「實模式」(8086/8088/80186/80286原生)中,地址是通過將段寄存器的內容乘以16(或等價地向左移四位)和添加偏移量。

在保護模式下(可用於80386和更高版本),段寄存器選擇一個包含基本物理地址的「描述符」。例如,操作數es:[bx]bx添加到該物理地址以生成操作數地址。