所以這應該是一個很容易回答的問題。如何在程序集中添加和減去大型變量?
想我給出了兩個非常大的變數一個和b,我想減b從一個。假設每個變量都是30個字。我不能只使用sub指導員嗎?我被告知,它將默認爲sub.w,並且只會從a的第一個字中減去b的第一個單詞。
那麼我該怎麼做呢?
所以這應該是一個很容易回答的問題。如何在程序集中添加和減去大型變量?
想我給出了兩個非常大的變數一個和b,我想減b從一個。假設每個變量都是30個字。我不能只使用sub指導員嗎?我被告知,它將默認爲sub.w,並且只會從a的第一個字中減去b的第一個單詞。
那麼我該怎麼做呢?
要執行多字減法,請從低位字開始,並從兩個變量中減去相應的字。使用sbb
指令處理借位,並僅在第1次減法中使用sub
。
mov dx, [ebx] ;First word of b
sub [eax], dx ;Subtract from 1st word of a
mov dx, [ebx+2] ;Second word of b
sbb [eax+2], dx ;Subtract from 2nd word of a
mov dx, [ebx+4] ;Third word of b
sbb [eax+4], dx ;Subtract from 3rd word of a
...
mov dx, [ebx+58] ;Thirtieth word of b
sbb [eax+58], dx ;Subtract from 30th word of a
一個更實際的解決方案使用一個循環:
mov ecx, 30
xor esi, esi ;This clears the CF, needed for the very first SBB
Again:
mov dx, [ebx+esi]
sbb [eax+esi], dx
lea esi, [esi+2]
loop Again ; loop without clobbering CF.
有better ways to write fast adc
/sbb
loops,但最優選擇的微架構之間變化。減少slowloop
instruction開銷的一種簡單方法是展開一點。
mov ecx, 15
xor esi, esi ;This clears the CF, needed for the very first SBB
Again:
mov dx, [ebx+esi]
sbb [eax+esi], dx
mov dx, [ebx+esi+2]
sbb [eax+esi+2], dx
lea esi, [esi+4]
loop Again
在優化此任務下一步驟是停止使用16位寄存器DX,而要用較大的EDX寄存器。這會將完全展開版本中的指令數量減半,或者將循環版本中的迭代次數減半以上。我們可以這樣做,因爲「30個字長的變量」可以被認爲是「15個雙字長的變量」。
這是完全展開的版本:
mov edx, [ebx] ;First dword of b
sub [eax], edx ;Subtract from 1st dword of a
mov edx, [ebx+4] ;Second dword of b
sbb [eax+4], edx ;Subtract from 2nd dword of a
mov edx, [ebx+8] ;Third dword of b
sbb [eax+8], edx ;Subtract from 3rd dword of a
...
mov edx, [ebx+56] ;Fifteenth dword of b
sbb [eax+56], edx ;Subtract from 15th dword of a
和部分展開循環版本:同樣使用RDX將進一步完善這些代碼
mov ecx, 5
clc ;This clears the CF, needed for the very first SBB
Again:
mov edx, [ebx] ; <1>
sbb [eax], edx
mov edx, [ebx+4] ; <2>
sbb [eax+4], edx
mov edx, [ebx+8] ; <3>
sbb [eax+8], edx
lea ebx, [ebx+12]
lea eax, [eax+12]
loop Again
顯然對x86-64的。請注意,儘管30個單詞對應於7個單詞和1個單詞。
添加和cmp clobber標誌。沒有「理想」的方式來執行多精度循環,因爲dec/jnz會導致部分標誌失速,而'循環'很慢。展開一下,使用笨重的東西有所幫助。 –
@PeterCordes感謝您發現'add'和'cmp'破壞了標誌。我編輯了答案。 –
你的編輯沒有強調循環而不用clobbering CF的事實是非平凡的。我做了一個編輯,無恥地鏈接到我自己的答案。隨意找到其他鏈接,比我更簡潔地解釋事情。我傾向於將自己的答案鏈接起來,因爲我記得它們存在並可以輕鬆找到它們。 :P –
閱讀關於adc和sbb的說明。 –
你在用什麼CPU? –