"一个简单的NASM汇编程序"为啥输不出结果?

时间:2022-09-30 01:09:55
代码如下:
;**************************gettime.asm***************************** 

ORG 0100H
CALL disptime
RET
;------------------------------------------------------------------
printub:
PUSHA
MOV AH, 0
MOV BL, 10                 ;BL=除数为10(十进制)
DIV BL                     ;AX/10
OR AX, 3030H               ;转换为ASCII数字
PUSH AX
MOV DL, AL                 ;商数,高位
MOV AH, 02H                ;显示
INT 21H
POP AX
MOV DL,AH                  ;余数,低位
MOV AH,02H                 ;显示
INT 21H
POPA
RET
;------------------------------------------------------------------
disptime:
PUSHA                    ;存储原来寄存器数据
MOV AH, 2CH                ;取得系统时间
INT 21H
MOV AL, CH                 ;小时(00-23)
CALL printub               ;显示小时
MOV DL, ':'                ;显示冒号(:)
MOV AH, 02H
INT 21H
MOV AL,CL
CALL printub
MOV DL, ':'
MOV AH, 02H
INT 21H
MOV AL,CL                  ;分(00-59)
CALL printub               ;显示分
MOV DL, ':'                ;显示冒号(:)
MOV AH,02H
INT 21H
MOV AL, DH                 ;秒数(00-59)
CALL printub               ;显示秒数
POPA                       ;恢复原来寄存器数据
RET

11 个解决方案

#1


你这不是 dos 类的程序吗,开头的 ret 指令换成相应的“结束程序返回DOS”的功能调用了

#2


用MASM编译

#3


引用 1 楼  的回复:
你这不是 dos 类的程序吗,开头的 ret 指令换成相应的“结束程序返回DOS”的功能调用了
那该怎么改啊?我初学的,你这句”开头的 ret 指令换成相应的“结束程序返回DOS”的功能调用了“不是很理解。。。

#4


引用 2 楼  的回复:
用MASM编译
NASM与MASM语法相对还是有区别的,这编译不会通过的吧。

#5


我是直接在nasm上编译成com文件(nasm gettime.asm -o gettime.com)但在dos上运行gettime.com显示不出结果。

#6


引用 3 楼  的回复:
那该怎么改啊?

你这个是 com 文件,最简单的修改就是改为 int20h 了;否则需要改为 mov ah, 4ch 和 int21h 两个指令。

#7


我改成mov ah, 4ch 和 int21h 后可以显示了,但这是什么原理呢?为什么要将ret改动呢?请教

#8


看这个表现,应该是在 Windows 的命令行窗口里吧,这个是虚拟的 dos 环境,其表现不完全是实时的,就和打印机的打印类似,不是发一个数据过去,它就立即打印出来的,往往是需要积累到一定的量,或者是遇到特定的控制功能比如换行或进页之类才会将所收到的内容展现出来。这样,当程序不能正常结束而失控了的话,这部分内容一可能就丢失了。如果是在纯 dos 下,即便是失控了,前面的显示内容应该是会有的。
另外,刚才看了下,好像在载入 com 文件时,dos 会将 fffc 开始的 4 字节置为 00 的,如果文件没有扩展名的话,用 debug 载入时就不会有这样的操作。所以,如果文件带 com 扩展名的话,你这个程序好像应该是可以正常运行的,因为 ret 到 0000 的话,那里是 psp:0000,正好有个 int20h 指令。你说不能,怎么个运行环境?我在 xp 的命令行窗口,dosbox下以及 vpc 的 dos622 下直接运行或 debug com 好像都可以的。

#9


引用 8 楼  的回复:
看这个表现,应该是在 Windows 的命令行窗口里吧,这个是虚拟的 dos 环境,其表现不完全是实时的,就和打印机的打印类似,不是发一个数据过去,它就立即打印出来的,往往是需要积累到一定的量,或者是遇到特定的控制功能比如换行或进页之类才会将所收到的内容展现出来。这样,当程序不能正常结束而失控了的话,这部分内容一可能就丢失了。如果是在纯 dos 下,即便是失控了,前面的显示内容应该是会有的。
……
你说的很透彻,但我在改ret前,确实能运行,但是这个程序不能输出系统的时间而是直接回到dos,不知什么原因。

#10


这种编译成com文件的asm程序很古怪,同一asm文件,编译成.com文件后执行,有时可以显示出结果,有时显示不出结果直接回到DOS,真郁闷。不过谢谢“zara”的回答。

#11


也得到什么更好的答案啦!

#1


你这不是 dos 类的程序吗,开头的 ret 指令换成相应的“结束程序返回DOS”的功能调用了

#2


用MASM编译

#3


引用 1 楼  的回复:
你这不是 dos 类的程序吗,开头的 ret 指令换成相应的“结束程序返回DOS”的功能调用了
那该怎么改啊?我初学的,你这句”开头的 ret 指令换成相应的“结束程序返回DOS”的功能调用了“不是很理解。。。

#4


引用 2 楼  的回复:
用MASM编译
NASM与MASM语法相对还是有区别的,这编译不会通过的吧。

#5


我是直接在nasm上编译成com文件(nasm gettime.asm -o gettime.com)但在dos上运行gettime.com显示不出结果。

#6


引用 3 楼  的回复:
那该怎么改啊?

你这个是 com 文件,最简单的修改就是改为 int20h 了;否则需要改为 mov ah, 4ch 和 int21h 两个指令。

#7


我改成mov ah, 4ch 和 int21h 后可以显示了,但这是什么原理呢?为什么要将ret改动呢?请教

#8


看这个表现,应该是在 Windows 的命令行窗口里吧,这个是虚拟的 dos 环境,其表现不完全是实时的,就和打印机的打印类似,不是发一个数据过去,它就立即打印出来的,往往是需要积累到一定的量,或者是遇到特定的控制功能比如换行或进页之类才会将所收到的内容展现出来。这样,当程序不能正常结束而失控了的话,这部分内容一可能就丢失了。如果是在纯 dos 下,即便是失控了,前面的显示内容应该是会有的。
另外,刚才看了下,好像在载入 com 文件时,dos 会将 fffc 开始的 4 字节置为 00 的,如果文件没有扩展名的话,用 debug 载入时就不会有这样的操作。所以,如果文件带 com 扩展名的话,你这个程序好像应该是可以正常运行的,因为 ret 到 0000 的话,那里是 psp:0000,正好有个 int20h 指令。你说不能,怎么个运行环境?我在 xp 的命令行窗口,dosbox下以及 vpc 的 dos622 下直接运行或 debug com 好像都可以的。

#9


引用 8 楼  的回复:
看这个表现,应该是在 Windows 的命令行窗口里吧,这个是虚拟的 dos 环境,其表现不完全是实时的,就和打印机的打印类似,不是发一个数据过去,它就立即打印出来的,往往是需要积累到一定的量,或者是遇到特定的控制功能比如换行或进页之类才会将所收到的内容展现出来。这样,当程序不能正常结束而失控了的话,这部分内容一可能就丢失了。如果是在纯 dos 下,即便是失控了,前面的显示内容应该是会有的。
……
你说的很透彻,但我在改ret前,确实能运行,但是这个程序不能输出系统的时间而是直接回到dos,不知什么原因。

#10


这种编译成com文件的asm程序很古怪,同一asm文件,编译成.com文件后执行,有时可以显示出结果,有时显示不出结果直接回到DOS,真郁闷。不过谢谢“zara”的回答。

#11


也得到什么更好的答案啦!