我正在使用NASM 16 BITS.我正在尝试做一个简单的汇编代码,打印0到255之间的数字,每个数字之间间隔1秒.这是我到目前为止:
[bits 16] mov ax,cs mov ds,ax mov cx,255 mov ax,0 myloop: ;print in screen ax value ;wait 1 second inc ax loop myloop
我不知道如何在屏幕上打印ax的值,以及如何等待1秒(将它们放在代码中的注释中).
在PC BIOS维护和更新的段0偏移46Ch(或者在段40h,关闭6Ch)有一个4字节计数器.它每秒增加18.2次.计算此计数器最低字节或字的18个变化可能是等待大约一秒钟的最简单方法:
原文链接:https://www.f2er.com/windows/371720.htmlmov ax,0 mov ds,ax mov cx,18 mov bx,[46Ch] WaitForAnotherChange: NoChange: mov ax,[46Ch] cmp ax,bx je NoChange mov bx,ax loop WaitForAnotherChange
要打印十进制数,您需要将二进制数转换为十进制数,获取单个数字并打印它们.您将数字除以10并收集余数.例如.:
123:
123/10:商12,余数3
12/10:商1,余数2
1/10:商0,余数1
通过重复除以10,您可以按相反的顺序得到余数中的各个数字:3,2,1.然后用DOS int 21h函数2打印它们(将2加载到AH中,将字符的ASCII码加载到DL中,执行int 21h).
另一种非常适合您的问题的变体是使用DAA指令直接以十进制递增数字而不进行任何转换.
以下是这一切的完成方式:
; file: counter.asm ; assemble: nasm.exe counter.asm -f bin -o counter.com bits 16 org 0x100 mov ax,0 ; initial number mov cx,256 ; how many numbers NextNumber: %if 1 ; change to 0 to use the DAA-based method push ax mov dx,0 div word [ten] push dx mov dx,0 div word [ten] push dx pop dx call PrintDigit pop dx call PrintDigit pop dx call PrintDigit pop ax call PrintNewLine call Wait1s inc ax %else mov dl,ah call PrintDigit mov dl,al shr dl,4 call PrintDigit mov dl,al and dl,0Fh call PrintDigit call PrintNewLine call Wait1s add al,1 daa adc ah,0 %endif loop NextNumber ret PrintDigit: pusha mov ah,2 add dl,'0' int 21h popa ret PrintNewLine: pusha mov dx,CRLF mov ah,9 int 21h popa ret Wait1s: pusha push ds mov ax,0 mov ds,ax mov cx,18 mov bx,[46Ch] WaitForAnotherChange: NoChange: mov ax,[46Ch] cmp ax,bx je NoChange mov bx,ax loop WaitForAnotherChange pop ds popa ret ten dw 10 CRLF db 13,10,"$"
如果您不喜欢前导零或最后1秒延迟,则可以有条件地跳过它们.
下载描述每条指令如何工作的Intel和/或AMD x86 cpu手册.读它们.另外,下载Ralf Brown的中断列表,它描述了每个BIOS和DOS功能.你需要知道其中一些做I / O.还有HelpPC和TechHelp可以方便地描述许多BIOS和DOS之类的东西,比如上述计数器所在的BIOS数据区.