2017-04-15 129 views
3

我想使用特定值初始化程序集中的數組。我試着先在循環中做它,但在數組中得到垃圾。然後我嘗試手動做,並得到同樣的垃圾。我希望數組重複n 1 2次n次。以下是我嘗試的一些示例代碼。將數組初始化爲程序集中的特定值(x86)

這是我嘗試手動加載數組。第一個值加載得很好。然而,當我在GDB中檢查它時,第二個值會加載垃圾。

sub esp, 260 
mov [ebp - 12], dword -1 
mov [ebp - 16], byte 0 
mov [ebp - 17], byte 1 
mov [ebp - 18], byte 2 
mov [ebp - 19], byte 0 
mov [ebp - 20], byte 1 
mov [ebp - 21], byte 2 
mov [ebp - 22], byte 0 
mov [ebp - 23], byte 1 
mov [ebp - 24], byte 2 
mov [ebp - 25], byte 0 

這是我嘗試自動做的。

sub esp, 260 
    mov [ebp - 12], dword -1 

again: 
    add [ebp - 12], dword 1 
    lea eax, [ebp - 16] 
    sub eax, [ebp - 12] 
    mov [eax], byte 0 

    add [ebp - 12], dword 1 
    lea eax, [ebp - 16] 
    sub eax, [ebp - 12] 
    mov [eax], byte 1 

    add [ebp - 12], dword 1 
    lea eax, [ebp - 16] 
    sub eax, [ebp - 12] 
    mov [eax], byte 2 

    cmp [ebp - 12], dword 255 
    jne again 
    jmp elsewhere 

使用NASM,X86-32,Intel語法。

編輯:當我轉換此代碼以DWORD而不是字節存儲數組值時,這兩種方法的工作。這是爲什麼?

+0

一個技巧:寫下你想在C到做什麼,並設置編譯器輸出組件,看看編譯器生成的並根據您的需求進行調整。 – slashmais

+0

它做了一些非常類似於我的手動方式。我會嘗試模擬它的作用,但我不明白我的情況有什麼不同。 – frillybob

+0

我無法複製生產線,因爲它不會因爲某種原因而編譯。但是,無論如何我都會得到同樣的垃圾。編輯當我將其轉換爲存儲dword而不是字節它可以以任何方式工作。這是爲什麼? – frillybob

回答

0

這裏是我的了:

;ecx = how much values ;ds:edi = destination 
function: 

    pushad     ;push all 32bit registers to stack 

    xor eax,eax    ;clear eax 

    function_loop: 

     push eax    
     mov ebx,0x00000003 ;we divide by 3 

     xor edx,edx   ;clear edx 

     div ebx    ;this stores the remainder of eax/0x03 in edx 
     mov DWORD [edi],edx ;move it to your array 

     pop eax    ;we dont need the result of the division 

     inc eax 
     add edi,4    ;increment pointer 4 bytes because 4 bytes are one DWORD 

    loop function_loop  ;loop til ecx is 0 

    popad      ;pop all 32bit registers 
ret 

我寫了我的頭,所以請報告它

但你有事情要做的就是增加一個寄存器中的任何錯誤,並做了模與3遞增寄存器,然後運行你有0,1,2模式

只是確保你對desitnation足夠的空間來存儲所有的N值

+1

'div edx'幾乎總是錯誤的,因爲具有32位操作數的_DIV_指令將操作數分成EDX:EAX中的64位值。所以你會做EDX:EAX/EDX,幾乎所有可能都會引起除法異常,因爲結果(商)不適合32位寄存器。 –

+0

@MichaelPetch哦,謝謝你,我沒有注意到, – SeeSoftware

1

使用NASM,您可以使用前綴times輕鬆初始化重複數據。例如,重複序列「0 1 2」 N倍於你的問題的要求,你可以做類似如下的內容:

section .data 

    my_array: times n db 0, 1, 2 

由你想要的恆定值,只需更換n。有關times前綴的更多信息可在NASM Manual中找到。

+0

在這種情況下,OPs數組是在棧上,所以你所建議的不適用。 –

+0

@MichaelPetch:實際上,如果我沒有弄錯,我認爲操作系統並不認爲堆棧上的數組是需要的,他只是想「初始化一個數組」。即使他的嘗試依賴於堆棧,他可能想要採取不同的做法,並採用我的答案中提出的簡單方法。 ;-) – Pyves

+0

我意識到他在他的問題中所說的話,從來沒有提到過堆棧,但是如果你看看他的代碼,你會看到他爲數組分配一個堆棧的chuck,然後嘗試填充它。不適用於堆棧,因爲它在內存中沒有固定的位置,您可以使用'times'指令。初始化堆棧上的數組需要一個編程方法。 –

0

這可能引發更多關於在堆棧上分配字節或雙字的想法。

您可能想要構建一個可以經常使用的個人函數或宏庫,或者查找%include包含的其他庫。

您可以按字節,雙字或其他大小解析數組數據,因爲您可以用同樣的方式處理所有數據元素。您必須始終注意數組元素的大小(例如,1對4字節..)。我會留下任何路線問題給你解決。

section .data 
     _len equ 64 
section .text 
     %macro mod 2 
     mov eax, %1 
     mov ebx, %2 
     xor edx, edx 
     div ebx     ; div/mul are very slow; but ok for small loops 
     mov eax, edx   ; return eax if you wish 
     %endmacro 

     global _start 
_start: 
     nop 

     sub esp, _len     ; 

     mov ecx, 1 
     L1: 

     mod ecx, 3      ; n mod 3 
     mov byte [esp+ecx], al 

     inc ecx 
     cmp ecx, _len     ; array size 
     jb L1 

     add sp, _len 

_exit: 
     mov eax, 1 
     mov ebx, 0 
     int 0x80 

GDB例如X/64D $ ESP使用next ....

(gdb) 
0xffffd180:  0  1  2  0  1  2  0  1 
0xffffd188:  2  0  1  2  0  1  2  0 
0xffffd190:  1  2  0  1  2  0  1  2 
0xffffd198:  0  1  2  0  1  2  0  1 
0xffffd1a0:  2  0  1  2  0  1  2  0 
0xffffd1a8:  1  2  0  1  2  0  1  2 
0xffffd1b0:  0  1  2  0  1  2  0  1 
0xffffd1b8:  2  0  1  2  0  1  0  0 
31  v eax, 1 
(gdb) 
0xffffd180:  0  1  2  0  1  2  0  1 
0xffffd188:  2  0  1  2  0  1  2  0 
0xffffd190:  1  2  0  1  2  0  1  2 
0xffffd198:  0  1  2  0  1  2  0  1 
0xffffd1a0:  2  0  1  2  0  1  2  0 
0xffffd1a8:  1  2  0  1  2  0  1  2 
0xffffd1b0:  0  1  2  0  1  2  0  1 
0xffffd1b8:  2  0  1  2  0  1  0  0 
25  cx, 3     ; n mod 3 
(gdb) 
0xffffd180:  0  1  2  0  1  2  0  1 
0xffffd188:  2  0  1  2  0  1  2  0 
0xffffd190:  1  2  0  1  2  0  1  2 
0xffffd198:  0  1  2  0  1  2  0  1 
0xffffd1a0:  2  0  1  2  0  1  2  0 
0xffffd1a8:  1  2  0  1  2  0  1  2 
0xffffd1b0:  0  1  2  0  1  2  0  1 
0xffffd1b8:  2  0  1  2  0  1  0  0 
27  cx 
(gdb) 
0xffffd180:  0  1  2  0  1  2  0  1 
0xffffd188:  2  0  1  2  0  1  2  0 
0xffffd190:  1  2  0  1  2  0  1  2 
0xffffd198:  0  1  2  0  1  2  0  1 
0xffffd1a0:  2  0  1  2  0  1  2  0 
0xffffd1a8:  1  2  0  1  2  0  1  2 
0xffffd1b0:  0  1  2  0  1  2 

    0