2010-10-26 74 views
0

我試圖用匯編語言編寫函數排序。它將對二維數組進行排序,使得行現在將按照字母順序包含數據。 我嘗試了很多東西,但它實際上超出了我目前的知識範圍。 這裏是我試過到目前爲止...對程序集中的字符串進行排序

.386 
public _Sort 
.model flat 
.code 
_Sort proc 

    push ebp 
    mov ebp, esp 
    push esi 
    push edi 

    mov edi, [esp + 4] ; address of destination array 
    mov esi, [esp + 8] ; address of source array 
    mov ecx, [esp + 16] ; # of elements to mov 
    cld 
    rep movsd 
L1: 
    mov eax, [esi] 
    cmp [esi + 8], eax 
    jg L2 
    xchg eax, [esi + 8] 
    mov [esi], eax 
L2: 
    pop edi 
    pop esi 
    pop ebp 

    ret  
_Sort endp 
end 

這裏的C++代碼...

#include <iostream> 

using namespace std; 

extern "C" int Sort (char [] [20], int, int); 

void main() 
    { 
    char Strings [10] [20] 
        = { "One", 
         "Two", 
         "Three", 
         "Four", 
         "Five", 
         "Six", 
         "Seven", 
         "Eight", 
         "Nine", 
         "Ten" }; 
    int i; 
    cout << "Unsorted Strings are" << endl; 
    for (i = 0; i < 10; i++) 
     cout << '\t' << Strings [i] << endl; 
    Sort (Strings, 10, 20); 
    cout << "Sorted Strings are" << endl; 
    for (i = 0; i < 10; i++) 
     cout << '\t' << Strings [i] << endl; 
    } 

我不知道我的組裝沒有任何意義,我們對此深感抱歉。

回答

2

您將需要在函數/過程中構建彙編代碼,就像您使用其他語言編寫代碼一樣。就像在C中一樣,字符串比較,複製等等,都需要在函數中完成。只是舉例:

; compares [esi] to [edi], returns +, 0 or - to indicate order 
; inputs: esi, edi: addresses of strings 
; destroys: esi, edi, edx 
; 
strcmp_int proc 
    jmp short start 
loop_top: 
    inc esi 
    inc edi 
start: 
    movsx eax, byte ptr [esi] 
    movsx edx, byte ptr [edi] 
    test edx, edx 
    jz @f 
    sub eax, edx 
    jz loop_top 
    ret 
@@: 
    sub eax, edx 
    ret 
strcmp_int endp 

[警告:此代碼不一定打算用作-是 - 只是種功能你通常需要編寫做這樣的一個示例彙編語言工作。由於我寫了很多彙編語言,所以你可以在現代處理器上做得更好 - 至少對於單純以彙編語言完成的事情,你通常希望把結果放在標誌中,而不是 -/0/+在像strcmp(和這個)產生的寄存器中。但是請注意,這確實返回由最後sub]

又見Why is memcmp so much faster than a for loop check?了一些鏈接優化的實現(SSE2/AVX2)顯式長度的字符串,設置標誌這可以更快的中長期串。一般優化鏈接,請參閱the x86 tag wiki

您的sort將取決於您決定實施的排序算法。顯然,Quicksort看起來不像插入排序。然而,主要觀點很簡單:不要試圖將其編寫成單一的,整體式的代碼塊—將其分解成易於編寫和理解的代碼段。

+0

'lodsb'已經增加了'esi'。使用'movzx eax,[esi]'來提高效率('lodsb'在Intel CPU上是3 uops,與'inc' /'movzx'不相稱)。還可以使用'cmp al,[edi]'代替sub,所以它可以在更多的CPU上與'jz'進行宏觀融合。 – 2017-11-26 10:57:45

+0

此外,如果它們等於終止'0'>,它將超過字符串的末尾。< – 2017-11-26 10:58:34

+0

顯然,爲了提高效率,您應該比較雙字或qword(或更好地使用SSE2)。使用SSE2,可以很容易地並行檢查每個字節是否爲'0',但對於普通整數代碼,您可以使用https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord。 (如果兩個隱含長度的字符串相互錯位,那麼更大的負載會變得非常棘手。[這並不像使用'strlen'進行對齊加載那樣簡單](https://stackoverflow.com/questions/37800739/它是安全可讀的 - 過去 - 在同一頁上的一個緩衝區在x86和x64)。) – 2017-11-26 11:03:43

相關問題