2012-10-18 42 views
1

我對程序集完全陌生,在將值分配給我的二維「數組」時遇到了問題。我的陣列是一個名爲screen.space,並且分配了HEIGHT * WIDTH * 4,所以有足夠的空間。我知道這是因爲在發出下面的命令之前,我循環訪問數組,並將所有值設置爲0,並通過打印出所有值來驗證它。)下面的命令只包含0值(我知道這是因爲在發出以下命令之前,我循環遍歷數組並將所有值設置爲0,並通過打印出所有值進行驗證)。將值分配給二維數組時的垃圾值

這是我做的:

movl $0, %eax 
movl $1, %ebx 
movl $20, screen(%eax, %ebx, 4) 

而這正是它導致了(列出所有的行和列時):

x:0 y:0 value:0 
x:0 y:1 value:20 
x:0 y:2 value:0 
x:0 y:3 value:0 
x:0 y:4 value:0 
x:1 y:0 value:335544320 
x:1 y:1 value:0 
x:1 y:2 value:0 
x:1 y:3 value:0 
x:1 y:4 value:0 
x:2 y:0 value:1310720 
x:2 y:1 value:0 
x:2 y:2 value:0 
x:2 y:3 value:0 
x:2 y:4 value:0 
x:3 y:0 value:5120 
x:3 y:1 value:0 
x:3 y:2 value:0 
x:3 y:3 value:0 
x:3 y:4 value:0 
x:4 y:0 value:20 
x:4 y:1 value:0 
x:4 y:2 value:0 
x:4 y:3 value:0 
x:4 y:4 value:0 

我所期待的只是看變化在screen[0][1]x:0 y:1 value:20。什麼導致這些「垃圾」值(335544320,1310720,5120等)?

正如我所說我是一個完整的初學者,所以很好!

編輯: 我提供了零填充函數和列出數組中的所有值的函數。

HEIGHT = 5 
WIDTH = 5 
EMPTY = 0 

.section .data 
counter: .int 0 
counter2: .int 0 

str3: .string "x:%d y:%d value:%d\n" 

.section .text 
################################# 
# Fill screen array with zeroes 
init_screen: 
################################# 
movl $0, counter 
init_screen_array_x: 

    movl $0, counter2 
init_screen_array_y: 
    movl counter, %ebx 
    movl counter2, %ecx 
    movl $EMPTY, screen(%ebx, %ecx, 4) 

    incl counter2 
    cmpl $HEIGHT, counter2 
    jl init_screen_array_y 

    incl counter 
    cmpl $WIDTH, counter 
    jl init_screen_array_x 

    ret 
################################# 
# end init_screen 
################################# 

################################# 
# Debugging function, list all values in array 
list_screen_array: 
################################# 
movl $0, counter 
list_screen_array_x: 

    movl $0, counter2 
list_screen_array_y: 
    movl counter, %ebx 
    movl counter2, %ecx 

    pushl screen(%ebx, %ecx, 4) 
    pushl counter2 
    pushl counter 
    pushl $str3 
    call printf 
    addl $16, %esp 

    incl counter2 
    cmpl $HEIGHT, counter2 
    jl list_screen_array_y 

    incl counter 
    cmpl $WIDTH, counter 
    jl list_screen_array_x 

    ret 
################################# 
# end list_screen 
################################# 

編輯2: 從安德烈亞斯輸入後,我做了這個功能:

# x should be stored in %eax 
# y should be stored in %ebx 
# saves address to screen[%eax][%ebx] in %eax 
screen_get_address: 
    imull $4, %eax 
    imull $4, %ebx 
    imull $WIDTH, %ebx 
    addl %ebx, %eax 
    addl screen, %eax 
    ret 

編輯3 目前仍然東西是不正確的。現在,當這樣做:

movl $0, %eax 
movl $2, %ebx 
call screen_get_address 
movl $20, (%eax) 

我得到(3×3個):

x:0 y:0 value:0 
x:0 y:1 value:0 
x:0 y:2 value:20 
x:1 y:0 value:0 
x:1 y:1 value:20 
x:1 y:2 value:0 
x:2 y:0 value:20 
x:2 y:1 value:0 
x:2 y:2 value:0 
+0

我會說程序按預期工作。你寫了一個20的位置。在啓動程序後,您不能指望剩餘的內存被零填充。事實上,它是未初始化的,即如果你想它包含零,明確填充零! –

+0

我也理解,但正如我所說的,在我執行'movl $ 20,屏幕(%eax,%ebx,4)'之前,數組只包含零值。我知道這一點,因爲我通過數組並顯式設置所有值爲零。所以'movl'也改變了其他地方的值! – Bazze

+0

嗯,我很確定movl命令寫入4個字節來解決「屏幕+4」,因此它將字節屏幕+ 4更改爲屏幕+7。我懷疑這個錯誤是在「零填寫」還是在你生成你在帖子中顯示的輸出的方式。 –

回答

1

你的代碼來計算的地址是錯誤的。 要訪問(%EBX = X,%ECX = y)處的二維DWORD陣列的需要在

screen + 4*(%ecx*WIDTH + %ebx) 

訪問數據要訪問屏元件(%EBX,%ecx中,4),其是

screen + %ebx + 4*%ecx 

即錯誤的位置。在movl指令之前,必須先生成地址(例如,使用MUL,或者如果WIDTH是2的冪,則使用移位指令)。如果您只想遍歷所有元素,則只需使用連續遞增的單個指針即可省去複雜的地址計算。

+0

謝謝!你能看看我做的功能,看看它是否正確?我更新了我的帖子! – Bazze

+0

似乎對我好。請注意,您可以通過用leal屏幕(,%eax,4),%eax(即eax = 4 * eax +屏幕)替換行addl屏幕%eax,來節省4美元,%ebx/%% ecx。 。地址也是無符號的(mul而不是imul),儘管這通常沒有區別。 –

+0

抱歉再次打擾您,我再次更新了我的帖子。它似乎並沒有正常工作: – Bazze