我想用英特爾I64彙編器做一些長整數運算(128位),並且需要創建2的補碼。假設我的正面價值是RDX:RAX。長整數的二進制補碼
2的補碼是通過「翻轉位和加1」完成的。所以最幼稚的做法是(4個指令和14個字節的代碼):
NOT RAX
NOT RDX
ADD RAX,1 ; Can't use INC, it doesn't set Carry
ADC RDX,0
當我使用RAX,而不是不NEG指令,但它的「+1」對我來說,但進是錯誤的,當RAX爲零時,NEG RAX清除進位,但我需要在這種情況下進位。因此,下一個最好的辦法可能是(4個指令和11個字節的代碼):
NOT RDX
NEG RAX
CMC
ADC RDX,0 ; fixed, thanks lurker
還是4個指令。但是不是加+1,我可以減1,並且由於SBB將進位位加到減數中,當進位清零時,我將加1。因此,我的下一個最好的嘗試是這樣的,有3個指令和10個字節的代碼:
NOT RDX
NEG RAX
SBB RDX,-1
正如你可以從我的長篇大論的文字看,這不明擺着理解。在彙編中有沒有更好的,更容易理解的方式來實現級聯二進制補碼?
您似乎認爲「更好」等於「更短的代碼」,並且這不必適用於無序多分頻處理器,就像x86-64一樣。我會說你的實現最容易理解是第一個,如果他們全部都執行相同的時間,我不會感到驚訝。 – 2015-04-03 20:08:40
順便說一句:你有沒有考慮過使用XMM寄存器?它們足夠寬以容納一個128位的數字,並且(我沒有檢查過)它們可能有整數指令來處理整數 – 2015-04-03 20:10:09
@mcleod_ideafix它們沒有,所以你仍然留下攜帶進位的問題手動。 – harold 2015-04-03 20:49:19