编辑:重写并添加文本,添加代码(在 MASM 6.11 中工作):
在 x86 汇编中,您需要为指令指定内存操作数的大小,否则会出现歧义。你必须告诉汇编器操作数的大小byte ptr
等等word ptr
。出于这个原因inc byte ptr ds:[count]
需要byte ptr
。inc word ptr ds:[count
是不同的指令。
mov dl,ds:[count]
不需要byte ptr
,因为dl
是一个 8 位寄存器,因此内存操作数的大小总是相同的,一个字节(8 位)。
要打印字符,您需要先将数字转换为字符串(对于小于 10 的数字或单个字符)。否则,您将打印具有 ASCII 代码 3 的控制字符 ETX(参见ASCII 表)。对于小于 10 的数字,以十进制打印很简单,只需添加 '0' ( 30h
),如下所示:
mov dl,ds:[计数]
添加 dl,'0' ; 添加 dl,30h
在 x86 汇编中以十进制打印是一个经常被问到的问题,例如看看这个代码是否正确(数字加数字,然后打印结果)来了解这个想法。
编辑: EXE 文件还需要一个堆栈段。
DOS EXE 文件需要有一个堆栈段。使用 MASM 6.11 进行汇编不会给出任何警告或错误,基本上是dosexe.asm
(将 dosexe.asm 替换为您的汇编代码文件名)。
但是与 ML ( ml dosexe.obj
) 链接会给出以下警告:
链接:警告 L4021:没有堆栈段
因此,需要添加一个堆栈段,将以下行添加到源代码的顶部。
.model 小
.stack 4096
数据段定义也有一些问题,我也修复了。
整个固定的汇编代码可能是这样的(在 MASM 6.11 中工作):
.model 小
.stack 4096
。数据
计数分贝 0
。代码
开始:
mov ax,seg 计数
mov ds,ax
inc 字节 ptr ds:[count]
inc 字节 ptr ds:[count]
inc 字节 ptr ds:[count]
; 此代码以十进制打印,无需反转
; 字符串,通过除数。100/10 = 10
移动 bl,100 ; 原始除数。
mov al,ds:[计数]
打印循环:
异或啊,啊;清除被除数的前 8 位(在 ax 中)。
div bl ; 将 ax 除以 bl。al 中的商,ah 中的余数。
移动dl,al;要打印的值 ah = 2, int 21h
移动,啊;余数在下一个循环中被除。
测试 dl,dl ; 检查数字是否为零
jz not_print ; 不要打印前导零。
添加 dl,'0' ; 转换为 ASCII 数字字符范围。
; '0' = 0x30 = 48
推斧
mov 啊,2
诠释 21 小时;根据 Ralf Brown's 打印值
流行斧; 中断列表返回 al。
not_print:
推斧
mov al,bl
异或啊,啊
移动 bl,10 ; 将除数除以 10。
div bl
mov bl,al ; 新的除数。
流行斧
测试 bl,bl
jnz 打印循环
mov ah,4ch
整数 21 小时
结束开始