Как отображать номера массивов один за другим (Irvine 32, библиотека Visual Studio 2019 ASM) - PullRequest
0 голосов
/ 06 февраля 2020

Мне нужно записывать каждый массив ручного ввода на экран один за другим, но когда я пытаюсь записать первый массив (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». Я запутался, почему есть разные выходы для разных способов записи первого массива на экран? Пожалуйста, помогите мне правильно вывести первый массив на экран.

1 Ответ

0 голосов
/ 10 февраля 2020

Массив, для которого вы ввели 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 , а скорее зависит от элемента смещения, Вот почему вы умножаете индекс на 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 записывает AX со смещением 1, перезаписывая, таким образом, часть 1-го и 2-го элементов массива

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

movzx eax, myArray[1] не извлекает 2-й элемент массива, поскольку даже если 1 правильный индекс , неправильный смещение . Это объясняет, почему у вас отображается 5.


Когда я использую mov myArray [0 * SIZEOF WORD], у меня появляется топор "Число в позиции 0 равно 5." но оно должно быть 1.

Просто потому, что вы фактически не загружали этот первый элемент в регистр EAX! Вы по ошибке записали в 1-й элемент с последующим отображением того, что произошло в EAX. И это было значение 5.

Когда я использую mov ax, myArray [0], вместо этого я получаю «Число в позиции 0 равно 1281».

На этот раз вы правильно прочитали 1-й элемент, но, учитывая, что часть вашей программы xchg нарушила 1-й и 2-й элементы, вы можете получить только то, что там есть.

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-го элемента!

...