2014-10-01 44 views
2

我有一個非常基本的問題: 你如何填充組裝數組?在高級編程語言中,可以使用for循環爲每個索引設置一個值,但我不確定如何完成同一個東西程序集。我知道這是錯的,但是這是我有:MASM大會(非常困惑的初學者)的陣列

ExitProcess PROTO 
.data 
warray WORD 1,2,3,4 
darray DWORD ? 

.code 
main PROC 
mov edi, OFFSET warray 
mov esi, OFFSET darray 
mov ecx, LENGTHOF warray 


L1: 
mov ax, [edi]   ;i want to move a number from warray to ax 
movzx esi,ax   ;i want to move that number into darray... 
add edi, TYPE warray ;this points to the next number? 

    loop L1 

    call ExitProcess 
main ENDP 
END 

每個循環運行時間,斧頭將與數組的索引值被覆蓋,對不對?相反,我如何使用warray的數組元素填充darray?任何幫助將非常感激......我很困惑。

回答

1

有多種方法來填充數組,並且您的代碼幾乎可以工作。一種方法是使用反間接地址,這樣你就不必修改目標和源數組指針每次循環:

ExitProcess PROTO 
.data 
    warray WORD 1,2,3,4 
    darray DWORD 4 dup (?) ; 4 elements 

.code 
main PROC 
    mov edi, OFFSET warray 
    mov esi, OFFSET darray 
    xor ecx, ecx    ; clear counter 
L1: 
    mov ax, [edi + ecx * 2]  ; get number from warray 
    movzx [esi + ecx * 4], ax ; move number to darray 
    inc ecx      ; increment counter 
    cmp ecx, LENGTHOF warray 
    jne L1 

    call ExitProcess 
main ENDP 
END 

當然這個代碼可以修改向後填補了數組可能保存情侶像你這樣的字節可能意味着你的原始代碼。這裏是具有更緊湊的循環另一種方式:

ExitProcess PROTO 
.data 
    warray WORD 1,2,3,4 
    darray DWORD 4 dup (?) ; 4 elements 

.code 
main PROC 
    mov edi, OFFSET warray 
    mov esi, OFFSET darray 
    mov ecx, LENGTHOF warray - 1 ; start from end of array 
L1: 
    mov ax, [edi + ecx * 2]  ; get number from warray 
    movzx [esi + ecx * 4], ax ; move number to darray 
    loop L1 

    ; get and set element zero separately because loop terminates on ecx = 0: 
    mov ax, [edi] 
    movzx [esi], ax 

    call ExitProcess 
main ENDP 
END 

你也應該注意到,與同類型的數組時,您可以非常有效地做簡單的複製使用重複前綴的指令就像MOVSD

ExitProcess PROTO 
.data 
    array1 DWORD 1,2,3,4 
    array2 DWORD 4 dup (?) 

.code 
main PROC 
    mov esi, OFFSET array1  ; source pointer in esi 
    mov edi, OFFSET array2  ; destination in edi 
    mov ecx, LENGTHOF array1 ; number of dwords to copy 
    cld       ; clear direction flag so that pointers are increasing 
    rep movsd     ; copy ecx dwords 
    call ExitProcess 
main ENDP 
END 
0

你可能並不是「應該知道」這一點,但無論如何,有一個指令和一個指令前綴被用來做這件事。

下面一起來看看這個微軟網頁:HERE (click on it)

在該頁面中,向下滾動,直到找到這句話...

」 ... 這些指令是在x86的CISC遺產的殘餘,在最近的處理器其實比寫了很長的路要走。的等效指令慢......」

你做的是...

  • 把數組的大小在Ecx
  • Edi在ARRY開始
  • 使用適當的字符串指令來填充它

語法(MASM/TASM的/ etc。)大概會是這個樣子......

Mov  Ecx, The_Length_Of_The_Array   ;Figure this out somehow 
Lea  Edi, The_Target_You_Want_To_Fill  ;Define this somewhere 

現在,如果你想從一個地方複製到另一個,這樣做...

現在
Lea  Esi, The_Source_You_Want_To_Copy   ;Whatever, define it 
Cld            ;This is the direction flag, make it inc 
Rep  Movsb         ;Movsb means move byte for byte 

,如果你要的東西在arrray每個字節做相同的值...

Mov  AL, The_Value_You_Want_To_Stuff   ;Define this to your liking 
Cld            ;This is the direction flag, make it inc 
Rep  Stosb         ;Stosb means store AL into each byte 

同樣,這些指令,原因他人將闡明,不再如果冷卻你用他們,你會得到cooties什麼的。

還有用於比較,「掃描」,「加載」等的字符串指令。他們曾經很有用(現在仍然是,但今天的「現代」團伙不會承認它),特別是添加了前綴Rep

如果這有幫助,但你需要更多的細節,隨時問。

+1

它們並不像你讓它們那樣糟糕。他們過去實施起來相當糟糕,但是在較新的體系結構(SNB +)上,它們實際上非常快。它們並不完全替代宏指令,但有一些情況下它們的表現比手寫彙編更好。 – drivingon9 2014-10-02 19:28:10

+0

@ drivingon9完全同意你的看法。用正確的方式寫出它們(我想,這是一個荒謬的文字遊戲),他們將完成少數其他指令可以完成的任務。現在看來,字符串指令已被標記爲通常不太酷。愚蠢?確實 !但是,這就是今天的生活。 – 2014-10-02 19:36:27

+0

丟失了編輯窗口時間。 @ drivingon9加上你的評論和我編輯我的答案。 – 2014-10-02 19:43:56