使用指向我的函数的指针 arg 会引发异常

Using a pointer arg to my function throws an exception

我目前在

行收到 "exception thrown" 错误
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

introduction 缺少一个 ret

执行从 introduction 的最后一条指令到 getData 的第一条指令。 machine-code 的执行总是继续到内存中当前指令之后的下一个地址(除非你使用 call/ret/branch);标签和 proc 声明只是标记。 (Why is no value returned if a function does not explicity use 'ret')

堆栈上没有有效指针时会发生这种情况。 (因为 main 先调用 introduction,而不是先推送地址。)


您可以通过 single-stepping 您的代码在调试器中查找此类错误; fall-through 而不是 return 到 main 应该引起你的注意!

或者使用调试器的回溯功能来查看调用的来源:您会看到从 call introduction 到达 getData 中的这一行,而不是从 call getData.


我建议在 getData 中使用 call-clobbered(也称为易失性)寄存器作为临时寄存器。 (EAX、ECX 或 EDX)。 ebx 通常是 call-preserved,因此 main 和 main 的调用者希望它们的 EBX 值在函数 return 时仍然存在。 (但是你的 main 没有 return 或使用 EBX,所以没有实际的错误,只是一个自定义调用约定。)