如何逐个显示数组编号(Irvine 32 库 Visual Studio 2019 ASM)



我需要将每个手动输入数组一个接一个地写入屏幕,但是当我尝试写入第一个数组(0(时,我得到的输出为5到屏幕。我还需要将第五个数组的值交换到第二个数组,我相信我已经正确完成了。 当程序运行时,它告诉我输入我的数字,所以我输入 1、2、3、4、5、6,但是 我的输出是 5?它应该是 1。 这是我的代码:


ExitProcess proto,dwExitCode:dword
.data       ;// write your data in this section
myArray WORD 6 DUP(? )
prompt BYTE "Enter a number", 0dh, 0ah, 0
prompt1 BYTE "The number at position 0 is ", 0dh, 0ah, 0
prompt2 BYTE "The number at position 1 is ", 0dh, 0ah, 0
prompt3 BYTE "The number at position 2 is ", 0dh, 0ah, 0
prompt4 BYTE "The number at position 3 is ", 0dh, 0ah, 0
prompt5 BYTE "The number at position 4 is ", 0dh, 0ah, 0
prompt6 BYTE "The number at position 5 is ", 0dh, 0ah, 0

.code       ;// write your program here
main proc


mov edx, OFFSET prompt
call WriteString
call ReadInt
mov myArray[0], ax
call WriteString
call ReadInt
mov myArray[1 * SIZEOF WORD], ax
call WriteString
call ReadInt
mov myArray[2 * SIZEOF WORD], ax
call WriteString
call ReadInt
mov myArray[3 * SIZEOF WORD], ax
call WriteString
call ReadInt
mov myArray[4 * SIZEOF WORD], ax
call WriteString
call ReadInt
mov myArray[5 * SIZEOF WORD], ax
mov ax, myArray[4 * SIZEOF WORD]
xchg myArray[1], ax
movzx eax, myArray[1]
call WriteDec
call Crlf

mov edx, OFFSET prompt1
call WriteString
mov myArray [0 * SIZEOF WORD], ax
call WriteDec
call Crlf 

当我使用mov myArray [0 * SIZEOF WORD], ax时,我得到"位置 0 处的数字是 5",但它应该是 1。 当我使用mov ax, myArray[0]而不是mov myArray [0 * SIZEOF WORD], ax时,我得到"位置 0 的数字是 1281"。我很困惑,为什么将第一个数组写入屏幕的不同方式有不同的输出? 请帮我把第一个数组正确地写到屏幕上。

您输入了 6 个值的数组将保存以下 12 个字节(以小端格式存储的 6 个单词(:

1,0,2,0,3,0,4,0,5,0,6,0  array
^   ^   ^   ^   ^   ^
0   1   2   3   4   5    index

当任务是将第五个数组元素与第二个数组元素交换时,您正确使用了数组元素索引 4 和 1,因为所有索引都从零开始。
现在,程序集编程中的数组寻址不使用元素索引,而是依赖于元素偏移量。这就是您将索引乘以SIZEOF WORD的原因。太糟糕了,您在与第二个数组元素交谈时忘记编写此比例因子。
事情是这样的:

mov ax, myArray[4 * SIZEOF WORD]在偏移量 8 处读取单词,因此AX变为 0005h。

1,0,2,0,3,0,4,0,5,0,6,0  array
^             ^
1             8        offset

xchg myArray[1], ax在偏移量 1 处写入AX,从而覆盖第 1 个和第 2 个数组元素的一部分

1,5,0,0,3,0,4,0,5,0,6,0  array
^             ^
1             8        offset

movzx eax, myArray[1]不会检索第二个数组元素,因为即使 1 是正确的索引,它也不是正确的偏移量。这就解释了为什么你会看到一个5。


当我使用 mov myArray [0 * SIZEOF WORD] 时,ax 我得到"位置 0 的数字是 5",但它应该是 1。

仅仅因为您实际上没有在EAX寄存器中加载第一个元素!您错误地写入了第一个元素,然后显示EAX中碰巧出现的任何内容。这就是值 5。

当我使用 mov ax, myArray[0] 代替时,我得到"位置 0 的数字是 1281"。

这次你正确地读取了第一个元素,但鉴于程序的xchg部分破坏了第一个和第二个元素,你只能得到里面的内容。

1,5,0,0,3,0,4,0,5,0,6,0  array
^
0                        offset

低字节为 1,高字节为 5。它们共同产生 1281 (1 + 256 * 5(。


试试这个:

; exchange the fifth and second elements
mov     ax, myArray[4 * SIZEOF WORD]   ; read 5th element
mov     dx, myArray[1 * SIZEOF WORD]   ; read 2nd element
mov     myArray[4 * SIZEOF WORD], dx   ; write new 5th element
mov     myArray[1 * SIZEOF WORD], ax   ; write new 2nd element
; print the first element
mov     edx, OFFSET prompt1
call    WriteString
movzx   eax, myArray[0 * SIZEOF WORD]   ; read 1st element
call    WriteDec
call    Crlf 

请注意,这里交换 2 个元素确实做到了它所说的。您的代码仅复制了第 5 个元素而不是第 2 个元素!

最新更新