Передача массива в процедуру, доступ к элементам с помощью Base+Offset

Я пытаюсь выполнить итерацию массива SDWORD из 10 элементов в процедуре. Я считаю, что в массиве есть все ожидаемые значения, потому что когда я отображаю их в основном, так и должно быть. Когда я передаю адрес массива процедуре, первый элемент работает, но каждый последующий элемент равен 0. Я испробовал все возможные варианты, и отладчик показывает правильные значения. Я просто не могу понять, где проблема.

Когда я перебираю массив в main, используя приведенное ниже, он отображается правильно.

    mov  ecx, 10    
        _displayTemp:       
             mov    ebx, ecx        
             sub    ebx, 10         
             mov    eax, numArray[ebx * TYPE finalNumber]       
             call   WriteInt        
             call   CrLf    
         loop   _displayTemp

Если я сделаю это, я получу все 0:

push OFFSET numArray    
call    bobBilby  

bobBilby PROC 

    push    ebp 
    mov ebp, esp
    mov esi, [ebp + 8]
    mov eax, [esi + 4]
    call    WriteInt
    call    CrLf
    mov eax, [esi + 8]
    call    WriteInt
    call    CrLf
    mov eax, [esi + 12]
    call    WriteInt
    call    CrLf
    ret 4

bobBilby ENDP

Я протестировал тот же код с массивом, в который вручную вводил данные, и он работает.

Если это имеет значение, код для вызова процедуры заполнения таков. Я использовал первый код выше, чтобы проверить его, и, похоже, он имеет все значения.

mov ecx, 10     
_fillArray:         
     mov    ebx, ecx        
     sub    ebx, 10                 
     <lots of push OFFSETs>         
     call   ReadVal         
     mov    eax, finalNumber        
     mov    numArray[ebx * TYPE finalNumber], eax   
loop    _fillArray

Я теряю его здесь, поэтому любая помощь будет потрясающей. Спасибо.

Обратите внимание, что ваш «рабочий» код отображает массив с конца назад, поэтому элементы начинаются с numArray и перемещаются в памяти вниз, а не вверх, как ожидалось. Если это сработает, значит, ваши значения находятся не в том месте, и поэтому bobBilby их не находит. Также в следующий раз опубликуйте минимальный воспроизводимый пример, который включает весь код и может быть скомпилирован и запущен другими, пытающимися помочь вам.

Jester 06.04.2022 00:17
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
2
1
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Счетчик циклов начинается в ecx с 10. И принцип работы loop: он уменьшается до нуля, а затем останавливается.

В каждой итерации:

  • вы фиксируете счетчик циклов ecx (который ведет обратный отсчет).
  • затем вычесть из этого 10

Итак, для первой итерации у вас есть 10-10, что нормально, но для второй итерации у вас есть 9-10 (что равно -1), для третьей итерации 8-10!

Вы должны выполнять это пошагово и иметь возможность реализовать это по крайней мере двумя способами во время пошагового выполнения: (1) что ebx отрицательно после вычитания 10 на второй итерации, и (2) что mov для сохранения в массиве заполняется память, которой нет в массиве — память, которая находится перед массивом.

Я бы сказал, что вы либо не выполняете один шаг, либо не выполняете проверку, которую должны выполнять после каждой инструкции. В любом случае вам нужно развивать свои навыки отладки.

Между тем, другие части этого кода продвигаются вперед по массиву, поэтому, вероятно, он не находит одинаковые значения.


В качестве еще одного метода отладки, если у вас есть сложная строка кода, замените ее несколькими более простыми строками кода, например:

вместо:

mov numArray[ebx * TYPE finalNumber], eax

сделайте что-то подобное, чтобы вы могли наблюдать все промежуточные значения.

sll ebx, 2                # verify ebx is right
add ebx, offset numArray  # verify the pointer value in ebx
mov [ebx], eax            # should be able to see exactly where stored

С этим последним mov вы должны убедиться, что значение в eax появляется в ячейке памяти, на которую ссылается ebx.

Для отладки режимов адресации lea edi, [whatever] / mov [edi], eax может позволить вам использовать тот же режим адресации, что и написанный, и по-прежнему видеть окончательный адрес. (Для загрузки вы можете LEA в место назначения загрузки, так как вы все равно перезаписываете его. Для хранилищ вам нужен временный.)

Peter Cordes 06.04.2022 04:54

Другие вопросы по теме