2014-09-24 116 views
0

我開始了我在彙編程序,我正在做一些算法和通用寄存器的數量是不夠的,這IA32-86使用專用寄存器作爲通用寄存器

有什麼辦法在asm中使用特殊寄存器(eip,eflags)作爲通用寄存器?

我只需要它們進行少量操作,但所有通用寄存器都已佔用,我不喜歡將值存儲在內存中,這會降低算法的性能。

可能嗎?

+3

您可以通過執行'jmp value'來寫入'eip'。你可以通過'call foo; foo:pop eax;'但是第一個可能有你不想要的副作用。 :)總之,沒有你不能使用'eip'和'eflags'作其他用途。 (並且大多數算術指令會隱式寫入'eflags') – Mysticial 2014-09-24 19:21:35

+2

幾乎你不能以實際的方式使用寄存器來達到預期的目的。如果您是彙編程序的新手,您可能還不知道如何組織代碼以最大限度地降低註冊壓力。而在某些地方,您只是明確地堅持特定算法的要求。作爲一般規則,如果您仔細編碼,您的代碼將運行得足夠快。編碼合理,讓它先運行,然後*擔心它是否太慢。 – 2014-09-24 19:52:39

+0

你可以用'sahf'將'ah'的某些位保存到'eflags'中,然後用'lahf'將它們加載到'ah'。您也可以使用'popf'將數據存儲到標誌中,但這可能會產生不必要的副作用。在實模式代碼(legacy或boot loader)中,你可以用cli來阻塞中斷,然後在某處存儲esp,使用esp作爲通用寄存器,加載esp的原始值並允許中斷'sti'。你可以使用'eip'來存儲一些數據。用'jmp eax' /'call eax',如果所有使用的值(跳轉目標)都有有效的代碼。無論如何,出於實際的目的,你最好遵循Ira Baxter的建議。 – nrz 2014-09-24 23:35:06

回答

0

簡短的回答是否定的。

如果你正在運行一個程序,使用eip作爲通用寄存器是絕對不可能的,就像你寫入eip一樣,你的程序將跳轉到該地址的運行指令(大致),這可能不會工作....至於EFLAGS,它有一些位被保留或控制你不想改變的各種事物,這又意味着它不能用作通用寄存器。由於您似乎有意不使用內存來保留值,因此可以使用esp和ebp(如果您使用堆棧,請小心)。除此之外,如果您將它們用作通用寄存器,則我認爲您使用的大多數寄存器都需要許可級別0來寫入並重新寫入,否則很可能會產生負面影響。

有可能是一些非常特殊的寄存器,特定於您的處理器,但如果您要使用它們,代碼將不會在處理器之間移植。

+0

在實模式和虛擬模式下,段寄存器(DS,ES,FS和GS,也可能是SS - 如果SP被錯用)也可用於存儲通用數據。然而,這些寄存器可以完成的操作非常有限。 – 2014-09-24 20:28:34

2

明智地重用已經可用的通用寄存器可能是您最好的選擇。仔細想想你的算法。

重新調整EIP是不可能的,並且使用EFLAGS作爲別的東西,雖然也許是可能的,但是太多的副作用通常是有用的。

更好的方法是實際使用內存計算您的算法。您可能會發現,由於緩存,訪問速度並不像您想象的那麼慢。

另一個選擇是使用數學協處理器的寄存器作爲一個小的私有堆棧來存儲,但這也可能不如簡單地使用存儲器那麼令人滿意。

2

簡短回答:不可以。那些寄存器並不打算明確寫入。你必須重寫你的算法,更好地分配你的寄存器,處理智能地溢出/重新加載寄存器到內存以最小化性能影響,或者如果可能的話,使用XMM寄存器來移動INT寄存器,或者在XMM方面做指令鏈。另一種選擇是使用64位來利用可用的額外寄存器。

0

我記得我使用調試寄存器dr0來存儲數據dr3。但我不確定他們使用的速度有多快。也許CPU內部的寄存器重命名(用於構建微操作)也可以讓它更高效。