我已经,只是为了好玩,开始学习汇编程序的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程序,但输出是相同的,也许有一点更乱码输出.我将尝试比较两个程序.
1条答案
按热度按时间dojqjjoe1#
我看到了一堆奇怪的角色,
DOS.PrintString函数09 h需要在DS:DX寄存器对中有一个远指针。当您的.EXE可执行文件启动时,DS段寄存器指向PSP(程序段前缀),但在这种情况下,您需要使其指向 hello 消息所在的
.data
部分:字符串
“一堆奇怪的字符”实际上是PSP和
.code
部分的文本表示,最后是.data
部分的(清晰)文本。但是这个过程崩溃了
每个程序都需要一个到调用方的出口(父进程通常是操作系统),而你没有提供出口!在第二个程序中(你找到的),这是由提到
.exit
处理的。终止DOS程序的首选方法是通过函数4Ch,在这里你可以在AL寄存器中提供一个退出码。使用0表示正常终止。
型
然后,父进程可以使用函数4Dh检查这个退出代码。
型
我的印象是,“$”是为字符串的终止,但上面的程序似乎附加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)。