masm x86 程序集崩溃中的 DOS 中断

Posted

技术标签:

【中文标题】masm x86 程序集崩溃中的 DOS 中断【英文标题】:DOS Interrupt in masm x86 assembly crashing 【发布时间】:2009-09-12 04:17:58 【问题描述】:

我刚刚开始在 win32 上学习一些 x86 程序集,并且使用 .asm 文件的 ide 附带的自定义构建规则将 masm 与 Visual Studio 2008 一起使用。我一直在尝试使用 DOS 中断打印到控制台,但我收到消息:“ASMTest.exe 中 0x00401004 处的未处理异常:0xC0000005:访问冲突读取位置 0xffffffff。”在第 8 行。我正在尝试输出单个 ascii 字符 'A' (41h) 这是 masm 代码:​​

.386
.MODEL flat, stdcall

.CODE
start:
    mov dl, 41h
    mov ah, 2
    int 21h
    ret
end start

当我使用 debug.exe,并使用“a”命令输入所有 .CODE 指令并运行它(“g”)时,它工作正常。

谁能告诉我如何正确使用 DOS 中断?谢谢!

编辑:在 win32 上编程时,Managu 是正确的,您应该使用像 WriteConsoleA 这样的 windows api 调用而不是使用 DOS 中断。 This 是一个有用的资源。如果有人正在寻找执行此操作的代码(就像我一样),这里是:

.386
.MODEL flat, stdcall

; Windows API prototypes
GetStdHandle proto :dword
WriteConsoleA proto :dword, :dword, :dword, :dword, :dword
ExitProcess proto :dword

STD_OUTPUT_HANDLE equ -11

.DATA
HelloWorldString db "hello, world", 10, 0

.CODE

strlen proc asciiData:dword
    ; EAX used as count, EBX as ascii char pointer, EDX (DL) as ascii char
    mov eax, -1
    mov ebx, asciiData
    mov edx, 0

    BeginLoop:
    inc eax       ; ++count (init is -1)
    mov dl, [ebx] ; *dl = *asciiptr
    inc ebx       ; ++asciiptr
    cmp dl, 0     ; if (*dl == '\0')
    jne BeginLoop ; Goto the beginning of loop

    ret
strlen endp

main proc
    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov ecx, eax
    invoke strlen, addr HelloWorldString
    invoke WriteConsoleA, ecx, addr HelloWorldString, eax, 0, 0
    ret
main endp

end

(设置入口点为main)

【问题讨论】:

【参考方案1】:

当您使用 debug.exe 输入此代码时,您正在组装一个 16 位(8086 架构,“实模式”)dos 程序。您指定的语义对于此类程序是正确的。但是,当您使用 MASM 组装您在此处获得的程序,然后链接它时,您正在尝试创建一个 32 位(i386 架构,“保护模式”)Windows 程序。我可能弄错了,但我认为在后一种情况下您甚至不能合法地调用 int 21h。

【讨论】:

@unknown:你甚至告诉 MASM 为你创建一个 32 位可执行文件 (.MODEL flat)【参考方案2】:

这可能是由于您的“ret”指令而发生的。你要回哪里?我想是记忆中某个未知的地方。

请尝试使用 int 20h。这将“优雅地”退出。

它可以在调试中工作(可能),因为那是一个更“受管理”的环境。

【讨论】:

【参考方案3】:

如果我们启动一个 16 位的 DOS-*.com 应用程序,那么 DOS 在我们的 PSP 中的偏移量 0 处填充“int 20”指令的操作码,并且在 DOS 让我们的应用程序执行。所以我们可以在代码末尾放置一个简单的“ret”指令。但是我们必须确保我们的堆栈指针没有损坏并且我们的代码段没有改变。

要使用 MASM 6+ 链接 16 位应用程序,我们需要一个 16 位链接器。

ftp://ftp.microsoft.com/softlib/mslfiles/lnk563.exe

德克

【讨论】:

以上是关于masm x86 程序集崩溃中的 DOS 中断的主要内容,如果未能解决你的问题,请参考以下文章

简单的 FASM “Hello world!” DOS中断崩溃

x86 AT&T 语法程序集的注释语法

将 ISR 链接到向量中断 80x86 32 位 AT&T 程序集

vs2017下汇编环境配置

x86 MASM - 传递和访问二维数组

如何在 Visual Studio 2017 的 x86 程序集中使用 printf?