【问题标题】:assembly - accessing array elements汇编 - 访问数组元素
【发布时间】:2012-07-23 19:15:47
【问题描述】:

我有一个正在尝试打印的数组。 我想把它打印出来,看看它是否正确。 它目前正在打印数字 1 并停止。或者,如果我以不同的方式处理 ECX,它会打印出一堆零并崩溃。

这是我的程序。

.data

array DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8)
my_size dd 10

sorted DWORD 0
first DWORD 0
second DWORD 0

.code

start:
main proc
cls

 mov EBX, offset[array]
 mov ECX, [my_size]
 dec ECX
 sub ESI, ESI
 sub EDI, EDI

; print
mov EBX, offset aa
sub ECX, ECX
;mov ECX, my_size
mov ECX, 10

my_loop:
mov EAX, [EBX]
inc EBX
dec ECX

cmp ECX, 0
jle exit_loop

mov first, EAX
print chr$("printing array elements: ")
print str$(first)

loop  my_loop

exit_loop:
ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

【问题讨论】:

  • 使用汇编编写 O(n^2) 排序算法使 zero 有意义。使用 [homework] 标签来回答家庭作业问题。

标签: arrays loops assembly masm32


【解决方案1】:

我不想这么说,但您还没有“准备好”编写冒泡排序。要么这是一个完全疯狂的家庭作业,要么你到目前为止还没有跟上这门课(可能两者都有)。

首先,我认为您没有正确定义数组。当我阅读您的代码时,您那里有 100 个双字 - 您指定的 10 个数字的 10 个副本。你不应该在那里需要“DUP”。

我会先打印未排序的数组,以确保您正确理解了该部分。您似乎正在使用几个宏,它们肯定不是指令。仅从名称来看,我猜(!)“print_chr$”打印一个字符,“print_str$”打印一个字符串(尽管您似乎正在打印您的字符串和数字 1)。如果你的宏集中有一个“print_int$”,我猜(!)这就是你想要的。因为我不熟悉你的宏,所以我可能是错的。

虽然您已将数组定义为“dword”,但您在排序例程中只比较单个字节。这可能适用于您使用的少量数字,但它并不正确。

进行冒泡排序的常用方法是在每次遍历数组的开始时将“标志”(寄存器或变量 - 这可能是“排序”的用途)设置为零,然后将其设置为 1每次你做一个交换。当你通过你的数组并且标志仍然为零时 - 你还没有进行交换 - 然后,只有这样,你的数组才会被排序。如果在每次通过后打印数组,您就会明白为什么它被称为“冒泡”排序 - 最小/最大数字“冒泡”到其最终位置。

您遍历双字数组 (esi * 4) 的代码看起来很正确(除了比较一个字节之外),但您的打印例程每次循环仅将 ebx 递增 1。 “添加 ebx, 4”或使用“ebx * 4”(不是两者)来打印双字。或者也许你的数组应该只是字节?

说真的,我会从更简单的东西开始 - 只需打印数组 - 并在完成之后添加排序例程。

希望对你有帮助。

最好, 弗兰克

【讨论】:

  • 您的遍历双字数组 (esi * 4) 的代码看起来很正确(除了只比较一个字节之外),我应该与 16 位寄存器进行比较吗?
  • 还不如使用完整的 32 位,不是吗?
  • 不要认为我有任何 32 位寄存器可以使用,我还没有使用它来替换 ah,以及 al 用于存储索引以进行比较。
  • edx 看起来并不忙。 ebp“通常”用作堆栈指针,但可以用作“通用”寄存器(因为您似乎没有堆栈帧)。
【解决方案2】:

我看到你已经简化了代码。好主意!我仍然不熟悉您使用的宏“print_str$”。在我看来,这不像打印数字那样“看起来”。你有“print_int$”或类似的吗?如果你能让它只打印第一个数字“5”,那将是一个好的开始。

现在...通过您的循环,您只需“inc ebx”。这不会让你获得下一个 dword,它会从第一个 dword 中获得字节 2、3 和 4,从第二个 dword 中获得第一个字节。由于您在(已删除的)排序代码中使用了“* 4”,因此您可能需要在此处使用“[ebx * 4]”。要么这样,要么每次通过循环将 4 添加到 ebx 。一个或另一个(但不是两者)应该逐步遍历一个 dwords 数组。

我怀疑第一步是选择“正确”宏来打印数字。从那里可能会变得更容易(?)。勇气! :)

最好, 弗兰克

【讨论】:

    猜你喜欢
    • 2013-03-01
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多