我是組裝新手,我正在嘗試在兩個陣列之間交換內容。到目前為止,我有這段代碼,經過測驗,我已經驗證它可以作業。但是,我想知道這是否是獲得所需結果的最有效方法,或者是否有另一種可能更有效的解決方案?
arrW WORD 100h, 200h, 300h
arrSW SWORD -140, 200, -300
mov ax, arrW
xchg ax, arrSW
xchg ax, arrW
mov ax, [arrW 2]
xchg ax, [arrSW 2]
xchg ax, [arrW 2]
mov ax, [arrW 4]
xchg ax, [arrSW 4]
xchg ax, [arrW 4]
uj5u.com熱心網友回復:
mov ax, arrW xchg ax, arrSW xchg ax, arrW mov ax, [arrW 2]
讓我印象深刻的第一件事就是第二件事xchg。在下面的指令中,在另一個加載 AX 之前加載 AX 暫存器是沒有意義的。因此,第一個在 8086 上也使速度提高 20% 的重寫是:
mov ax, [arrW]
xchg ax, [arrSW]
mov [arrW], ax
mov ax, [arrW 2]
xchg ax, [arrSW 2]
mov [arrW 2], ax
mov ax, [arrW 4]
xchg ax, [arrSW 4]
mov [arrW 4], ax
避免使用xchg指令的解決方案不會在 8086 上付費,但通常是在 x86 上進行的方式。例如。下一個片段在 8086 上慢了 10%:
mov ax, [arrW]
mov bx, [arrSW]
mov [arrW], bx
mov [arrSW], ax
回圈無法擊敗您當前展開的代碼,但如果陣列應該變得更大,那么接下來就是它的樣子:
mov cx, 3
mov si, OFFSET arrW
mov di, OFFSET arrSW
More:
mov ax, [si]
mov dx, [di]
mov [si], dx
mov [di], ax
add si, 2
add di, 2
dec cx
jnz More
如果陣列arrW和arrSW在記憶體中彼此跟隨,則相同的回圈最好寫為:
mov bx, OFFSET arrW
More:
mov ax, [bx]
mov dx, [bx 6]
mov [bx], dx
mov [bx 6], ax
add bx, 2
cmp bx, OFFSET arrSW
jb More
如果 CPU 支持 32 位暫存器,那么使用這些 dword 可以將所需的迭代次數減半。如果元素的數量是奇數,我們剝離一個單詞大小的交換:
mov cx, 39
mov si, OFFSET arrW
mov di, OFFSET arrSW
shr cx, 1
jnc More ; Count was even
mov ax, [si]
mov dx, [di]
mov [si], dx
mov [di], ax
add si, 2
add di, 2
More:
mov eax, [si]
mov edx, [di]
mov [si], edx
mov [di], eax
add si, 4
add di, 4
dec cx
jnz More
上面的代碼在回圈開始時剝離了一個字大小的交換。正如@PeterCordes 在此答案下方的評論中所寫,通常最好將剝離的交換放在最后(出于資料對齊的原因)。接下來是那個版本:
mov cx, 39
mov si, OFFSET arrW
mov di, OFFSET arrSW
shr cx, 1 ; -> CF is set if count is odd
jz Next \
More: |
mov eax, [si] |
mov edx, [di] |
mov [si], edx |
mov [di], eax | Nothing changes the CF
lea si, [si 4] |
lea di, [di 4] |
dec cx |
jnz More |
Next: /
jnc Done ; (*) Count was even
mov ax, [si]
mov dx, [di]
mov [si], dx
mov [di], ax
Done:
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/519518.html
標籤:Intel Collective 数组部件x86x86-16
