3

我刚刚开始在 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 中断。是一个有用的资源。如果有人正在寻找执行此操作的代码(就像我一样),这里是:

.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)

4

3 回答 3

3

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

于 2009-09-12T05:10:33.537 回答
0

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

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

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

于 2009-09-12T04:43:48.563 回答
0

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

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

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

短剑

于 2013-05-05T15:42:09.540 回答