【问题标题】:Using a pointer arg to my function throws an exception使用指向我的函数的指针 arg 会引发异常
【发布时间】:2019-05-25 17:03:12
【问题描述】:

我目前在线上遇到“抛出异常”错误

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

【问题讨论】:

    标签: exception assembly x86 masm masm32


    【解决方案1】:

    introduction 缺少ret

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

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


    您可以通过单步执行代码在调试器中查找此类错误;失败而不是返回 main 应该会引起您的注意!

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


    我建议对 getData 内部的临时寄存器使用 call-clobbered(又名 volatile)寄存器。 (EAX、ECX 或 EDX)。 ebx 通常是保留调用的,因此 main 和 main 的调用者希望它们的 EBX 值在函数返回时仍然存在。 (但是您的 main 不会返回或使用 EBX,因此没有实际的错误,只是自定义调用约定。)

    【讨论】:

    • 谢谢!这几天我一直为此感到压力,我什至把它展示给我的同学们,他们都被难住了。
    • @AeijanB:是的,很难注意到不存在的东西。这就是为什么使用调试器对于发现简单错误非常有帮助的原因,如果您不单步执行,这些错误会导致令人困惑的错误。你应该告诉你的同学使用调试器;在没有人的情况下编写 asm 就像试图构建一个蒙着眼睛的机器人。
    • @AeijanB:另外,如果这解决了你的问题,别忘了点击“接受”复选标记(在投票箭头下)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多