2014-07-04 52 views
2

我正在通過Micheal Abrash的圖形編程黑皮書(順便說一句,我非常喜歡,我強烈推薦它),所以我正在使用的示例代碼非常古老。不過,我看不出有什麼問題:似乎無法將%ES添加到clobberlist(內聯彙編,GCC)

__asm__(
    //Some setup code here 
    "movl %%esi, %%edi;" 
    "movw %%ds, %%es;" 
    //A whole bunch more assembly code in between 
    "divloop:" 
    "lodsw;" 
    "divl %%ebx;" 
    "stosw;" 
    "loop divloop;" 
    //And a little more code here 
    : "=r" (ret) 
    : "0" (ret) /*Have to do this for some reason*/, "b" (div), "c" (l), "S" (p) 
    : "%edi", "%es" 
); 
  • l變量是一個unsigned int,該p變量是一個char *。 l 是由p指向的字符串的長度的字節計數。 div 是除數,是一個無符號整數。 ret是該函數的返回值(一個 無符號整數),並在內部設置爲彙編塊至 爲除法的其餘部分。

我收到的錯誤信息是「錯誤:'asm'中的未知寄存器名稱'%es'」(這是唯一的錯誤信息)。我最好的猜測是它在GAS語法中有另一個名字。我知道我正在使用舊代碼,但據我所知,在我相當新的intel i3上仍然有一個ES寄存器被stos使用*

其次,有一個問題困擾着我。我基本上別無選擇,只能假設DS已經設置到正確的內存位置以便與lods *一起使用。因爲我正在讀取,修改和寫入相同的內存位置(使用stos *和lods *),所以我將ES設置爲DS。但是,真的讓我感到害怕,我的DS可能是任何東西,我不知道還有什麼可以設置的。更重要的是,ESI和EDI已經是32位寄存器,並且應該足以自己訪問內存。

根據我的經驗,兩個奇怪的問題一次通常是由一個更基本的問題(通常是一個PEBKAC)相關和引起的。然而,我很困惑這一點。有誰知道發生了什麼事?

謝謝一堆

P.S.我試圖重新創建第9章中的代碼(提示我的讀者給我,代碼9.5,第182頁),它將EBX中存儲在連續內存中的大量數據分開。除了我個人的成長和娛樂之外,沒有其他理由這樣做。

回答

5

如果您運行的是32位平面保護模式環境(如Linux或Windows用戶模式進程),則無需設置es。

段寄存器是由OS爲您設置的,並且es和ds都允許您訪問一個扁平的32位地址空間。

GCC不會生成保存/恢復段寄存器的代碼,所以它不會讓您將它們添加到clobber列表中並不奇怪。

+0

謝謝,那就是我正在尋找的。 – Mahkoe