Использование указателя arg для моей функции вызывает исключение - PullRequest
2 голосов
/ 25 мая 2019

В настоящее время я получаю сообщение об ошибке "исключение" в строке

mov      [ebx], eax

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

Это точная копия моих заметок к лекции, и, похоже, она работает для других людей, кроме меня.


 TITLE Program Template     (template.asm)

; Author:
; Last Modified:
; OSU email address: 
; Course number/section:
; Project Number:                 Due Date:
; Description:

INCLUDE Irvine32.inc

.data
intro           BYTE    "Fun with Arrays! by ", 0
instruction BYTE    "This program generates random numbers in the range [100 .. 999], displays the original list, sorts the list, and calculates the median value. Finally, it displays the list sorted in descending order.", 0


request         DWORD   ?
ask_user        BYTE    "How many numbers should be generated? [10 ... 200]: ", 0

.code
main PROC

    ;call   randomize
    call    introduction

    push    OFFSET request
    call    getData

    exit    ; exit to operating system
main ENDP

introduction PROC
     mov    edx, OFFSET intro
     call   WriteString
     call   CrLf
     mov    edx, OFFSET instruction
     call   WriteString
     call   CrLf
introduction ENDP

getData PROC
    push    ebp
    mov     ebp, esp

    mov     edx, OFFSET ask_user
    call    WriteString
    call    ReadInt
    mov     ebx, [ebp+8]
    mov     [ebx], eax
    pop     ebp
    ret     4
getData ENDP

END main

1 Ответ

2 голосов
/ 25 мая 2019

introduction отсутствует ret

Выполнение выполняется от последней инструкции introduction до первой инструкции getData.Выполнение машинного кода всегда продолжается до следующего адреса в памяти после текущей инструкции (если вы не используете вызов / ret / branch);метки и proc объявления являются просто маркерами.( Почему не возвращается значение, если функция не является явным, используйте 'ret' )

Это происходит без действительного указателя на стек.(Поскольку main сначала вызывает introduction, не нажимая сначала адрес.)


Подобные ошибки можно искать в отладчике, пошагово выполняя код;падение вместо возврата к главному должно привлечь ваше внимание!

Или используйте функцию возврата вашего отладчика, чтобы увидеть, откуда поступил вызов: вы увидите, что достигли этой строки в getData из call introduction, не из call getData.


Я бы рекомендовал использовать закрытый вызовом (он же энергозависимый) регистр для временного внутри getData.(EAX, ECX или EDX).ebx обычно сохраняется с сохранением вызовов, поэтому main и вызывающая сторона main ожидают, что их значение EBX останется, когда функции вернутся.(Но ваш main не возвращает и не использует EBX, поэтому здесь нет реальной ошибки, только пользовательское соглашение о вызовах.)

...