assembly x86 MS Macro Assembler Hello World程序崩溃

3zwjbxry  于 11个月前  发布在  Mac
关注(0)|答案(1)|浏览(141)

我已经,只是为了好玩,开始学习汇编程序的x86架构,它的东西我一直想知道更多.我使用微软宏汇编v6.11运行在IBM PC DOS 2000(VM)一切都运行得很好,操作系统,汇编程序,链接器,等.但当我尝试运行这个程序:

.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

字符串
我得到了一堆奇怪的字符和你好,世界在年底,但该进程崩溃,因为它在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


这个程序,工作正常,没有乱码输出,根据评论,我的印象是,“$”是字符串的终止,但上面的程序似乎附加0 dh,0ah,0到字节定义的“消息”我已经尝试适应这在我原来的hello world程序,但输出是相同的,也许有一点更乱码输出.我将尝试比较两个程序.

dojqjjoe

dojqjjoe1#

我看到了一堆奇怪的角色,
DOS.PrintString函数09 h需要在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


我的印象是,“$”是为字符串的终止,但上面的程序似乎附加0 dh,0ah,0到字节定义的“消息”我已经试图适应这在我原来的hello world程序,但输出是相同的

$-终止专门用于DOS.PrintString函数09 h。其他程序没有使用函数09 h,而是使用DOS.WriteFileOrDevice函数40 h,并使用STDOUT的预定义句柄1。由于其操作基于字节计数,* message* 是否以零结尾并不重要。但是它会显示一个空格字符,这有时会把事情搞砸。

13,10还是不转13,10

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

相关问题