如何对字大小的数组中的元素进行寻址以交换和显示值?

问题描述 投票:0回答:1

我需要将手动输入的数组元素逐个写入屏幕,但是当我尝试写入第一个数组元素时,我在屏幕上得到的输出为 5。
我还需要将第五个数组元素与第二个数组元素交换,我相信我已经正确完成了。
当程序运行时,它告诉我输入数字,所以我输入1,2,3,4,5,6,但我的输出是5?应该是1。

这是我的代码:

INCLUDE c:\Irvine\Irvine32.inc

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]
代替时,我得到“位置 0 处的数字是 1281。”
我很困惑,为什么将第一个数组元素写入屏幕的不同方式有不同的输出?

arrays assembly x86 visual-studio-2019 irvine32
1个回答
0
投票

您为其输入 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,因为所有索引都从零开始。
现在,汇编编程中的数组寻址不使用元素indexes,而是依赖于元素offsets。这就是为什么您将索引乘以

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,5,0,0,3,0,4,0,5,0,6,0  array
  ^             ^
  1             8        offset

movzx eax, myArray[1]
不会检索第二个数组元素,因为即使 1 是正确的 index,它也不是正确的 offset。这解释了为什么您会显示 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 个元素!

© www.soinside.com 2019 - 2024. All rights reserved.