x86 MS 宏汇编器 Hello World 程序崩溃

问题描述 投票:0回答:1

我只是为了好玩,开始学习 x86 架构的汇编程序,这是我一直想了解更多的东西。我正在使用在 IBM PC DOS 2000 (VM) 下运行的 Microsoft Macro Assembler v6.11,一切都运行良好,操作系统、汇编器、链接器等。但是当我尝试运行此程序时:

.model small
.stack 100h
.data
    hello db 10,13,"Hello World$"
.code
    main proc
    lea dx, hello
    mov ah, 9h
    int 21h
    main endp
    end main

最后我得到了一堆奇怪的字符和Hello, world,但是进程崩溃了,因为它在DOS下运行,我别无选择,只能ctrl-atl-delete并重新启动。我想知道我做错了什么?我的猜测是我不知何故出界了,但我显然对此还了解得不够。

我执行以下操作来汇编和链接程序:

ml hello.asm

这不会产生错误或警告,我也尝试过手动汇编和链接程序:

masm hello.asm
link hello.obj

这也没有给出错误或警告,但程序仍然无法运行

该程序已在IBM PC DOS 2000和Microsoft Windows 98 SE下进行了测试,结果是相同的,只不过它只是运行该程序的进程在Windows下崩溃。

这是生成的列表,如果有任何用处:

Microsoft (R) Macro Assembler Version 6.11          12/20/23 15:42:42
hello.asm                            Page 1 - 1


                .model small
                .stack 100h
 0000               .data
 0000 0A 0D 48 65 6C 6C         hello db 10,13,"Hello World$"
       6F 20 57 6F 72 6C
       64 24
 0000               .code
 0000                   main proc
 0000  8D 16 0000 R         lea dx, hello
 0004  B4 09                mov ah, 9h
 0006  CD 21                int 21h
 0008                   main endp
                    end main
Microsoft (R) Macro Assembler Version 6.11          12/20/23 15:42:42
hello.asm                            Symbols 2 - 1




Segments and Groups:

                N a m e                 Size     Length   Align   Combine Class

DGROUP . . . . . . . . . . . . .    GROUP
_DATA  . . . . . . . . . . . . .    16 Bit   000E     Word    Public  'DATA'    
STACK  . . . . . . . . . . . . .    16 Bit   0100     Para    Stack   'STACK'    
_TEXT  . . . . . . . . . . . . .    16 Bit   0008     Word    Public  'CODE'    


Procedures,  parameters and locals:

                N a m e                 Type     Value    Attr

main . . . . . . . . . . . . . .    P Near   0000     _TEXT Length= 0008 Public


Symbols:

                N a m e                 Type     Value    Attr

@CodeSize  . . . . . . . . . . .    Number   0000h   
@DataSize  . . . . . . . . . . .    Number   0000h   
@Interface . . . . . . . . . . .    Number   0000h   
@Model . . . . . . . . . . . . .    Number   0002h   
@code  . . . . . . . . . . . . .    Text     _TEXT
@data  . . . . . . . . . . . . .    Text     DGROUP
@fardata?  . . . . . . . . . . .    Text     FAR_BSS
@fardata . . . . . . . . . . . .    Text     FAR_DATA
@stack . . . . . . . . . . . . .    Text     DGROUP
hello  . . . . . . . . . . . . .    Byte     0000     _DATA 

       0 Warnings
       0 Errors

更新

我发现了这个:

TITLE Hello World

.model small
.stack 100h

.data
message BYTE "Hello World",0dh,0ah,0

.code
main PROC
    mov ax,@data
    mov ds,ax

    mov ah,40h
    mov bx,1
    mov cx,SIZEOF message
    mov dx,OFFSET message
    int 21h

    .exit
main ENDP
END main

这个程序工作正常,没有乱码输出,根据评论,我的印象是“$”是字符串的终止,但上面的程序似乎将 0dh,0ah,0 附加到定义的字节中“message” 我试图在我原来的 hello world 程序中调整它,但输出是相同的,也许有更多的乱码输出。我会尝试比较这两个程序。

assembly x86-16 dos masm
1个回答
0
投票

我得到了一堆奇怪的字符,最后是“你好,世界”

DOS.PrintString 函数 09h 需要 DS:DX 寄存器对中的远指针。当您的 .EXE 可执行文件启动时,DS 段寄存器指向 PSP(程序段前缀),但在这种情况下,您需要使其指向您的

hello
消息所在的 .data 部分:

mov  ax, @data
mov  ds, ax

“一堆奇怪的字符”实际上是 PSP 和

.code
部分的文本表示,最后是
.data
部分的(清晰的)文本。

但是进程崩溃了

每个程序都需要对其调用者进行退出(父进程通常是操作系统),而您没有提供退出!在第二个程序(您找到的)中,这是通过提及

.exit
来处理的。
终止 DOS 程序的首选方法是通过函数 4Ch,您可以在 AL 寄存器中提供退出代码。使用 0 进行正常终止。

mov  ax, 4C00h  ; DOS.TerminateWithExitcode
int  21h

之后,父进程可以使用函数 4Dh 检查此退出代码。

mov  ah, 4Dh    ; DOS.GetExitcode
int  21h        ; -> AH exitcode system, AL exitcode child

我的印象是“$”是字符串的终止,但上面的程序似乎将 0dh,0ah,0 附加到为“message”定义的字节中,我尝试在我原来的 hello world 程序中调整它,但输出是相同的

$ 终止符专门与 DOS.PrintString 函数 09h 一起使用。该另一个程序没有使用函数 09h,而是使用 DOS.WriteFileOrDevice 函数 40h 以及 STDOUT 的预定义句柄 1。因为它的操作基于字节数,所以 message 以零结尾并不重要。然而,它会显示一个空格字符,有时可能会有点混乱。

13,10
或不去
13,10

DOS 中的换行需要回车符 (13) 和换行符 (10)。在真实的 DOS 环境中,顺序并不重要,几乎每个人都使用 (13, 10),但某些模拟器可能不喜欢其中之一。我相信是 emu8086 不是特别喜欢 (13, 10)。

© www.soinside.com 2019 - 2024. All rights reserved.