将值分配给二维数组时的垃圾值
Posted
技术标签:
【中文标题】将值分配给二维数组时的垃圾值【英文标题】:Garbage values when assigning values to two dimensional array 【发布时间】:2012-10-18 20:25:47 【问题描述】:我对汇编完全陌生,在为我的二维“数组”赋值时遇到了一个问题。我的数组是一个名为screen
的.space
,并分配了HEIGHT * WIDTH * 4
,所以有足够的空间。
在我执行数组下方的命令之前,数组仅包含 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: 在 Andreas 的输入之后,我做了这个函数:
# 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)
我得到(3x3 数组):
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
【问题讨论】:
我会说程序按预期工作。你在写它的位置上有一个 20。您不能期望在启动程序后剩余的内存会被零填充。事实上它是未初始化的,也就是说,如果你想让它包含零,明确地用零填充它! 我也明白这一点,但正如我所说,在我执行movl $20, screen(%eax, %ebx, 4)
之前,数组只包含零值。我知道这一点,因为我遍历了数组并将所有值显式设置为零。所以不知何故,movl
也改变了其他地方的值!?
嗯,我很确定 movl 命令将 4 个字节写入地址“screen+4”,因此它将字节 screen+4 更改为 screen+7。我怀疑错误出在“零填充”或您生成帖子中显示的输出的方式中。
感谢您的宝贵时间。我用我的零填充和列表功能编辑了我的帖子!
【参考方案1】:
您计算地址的代码有误。 要访问 2D dword 数组的 (%ebx=x,%ecx=y) 元素,您需要访问以下位置的数据
screen + 4*(%ecx*WIDTH + %ebx)
你正在访问screen(%ebx, %ecx, 4),即
screen + %ebx + 4*%ecx
即错误的位置。在您的 movl 指令之前,您必须首先生成地址(例如,使用 MUL,或者,如果 WIDTH 是 2 的幂,则使用 shift 指令)。如果只想循环遍历所有元素,只需使用一个不断递增的指针即可省去复杂的地址计算。
【讨论】:
谢谢!你能看看我做的功能,看看它是否正确?我更新了我的帖子! 对我来说似乎没问题。请注意,您可以通过将行 addl screen, %eax 替换为 leal screen(,%eax,4),%eax (即 eax = 4*eax + screen)来节省 imul $4, %ebx/%%ecx .地址也是无符号的(mul 而不是 imul),尽管这通常没有区别。 很抱歉再次打扰您,我再次更新了我的帖子。毕竟它似乎无法正常工作:( 我没有看到任何错误,如果找不到错误,您可能需要运行调试器。以上是关于将值分配给二维数组时的垃圾值的主要内容,如果未能解决你的问题,请参考以下文章
从二维数组中的“char *”类型错误分配给“char [100] [100]”类型时的类型不兼容