问题描述
我正在弄乱一些NASM代码,该代码对数字做一些数学运算并打印出与答案相对应的ASCII字符。这是代码:
Pin<&mut Self>
在vm上运行时,它会打印出“ e”并正常工作。但是,当在启动USB设备的真实计算机上运行时,它变得异常复杂。我必须清除所有寄存器,甚至不需要清除的寄存器,然后将答案从一个寄存器移到另一个寄存器,以使其起作用。我不知道为什么需要这样做。如果代码略有不同,即使没有清除cx和dx之类的内容,也不会打印任何内容。为什么会这样呢?任何帮助表示赞赏。
解决方法
标准int 10h
仅需要设置ax
和bx
,看来您已正确完成此操作。顶部bx
的计算设置为零,ax
的计算设置为0865H
:
mov ax,1853 ; ax <- 073dH
mov bl,15 ; bx <- ??0fH
div bl ; ax <- 087bH
sub al,2 ; ax <- 0879H
mov bx,10 ; bx <- 000AH
subtract: ; ten times decrement bx,sub 2 from ax
sub ax,2
sub bx,1
cmp bx,0
jne subtract ; ax <- 0865H,bx <- 0000H
然后根据需要设置寄存器:
mov bl,al ; bx <- 0065H
mov ax,0 ; ax <- 0000H
mov cx,0 ; cx <- 0000H
mov dx,0 ; dx <- 0000H
mov ah,0x0e ; ax <- 0e00H
mov al,bl ; ax <- 0e65H
mov bx,0 ; bx <- 0000H
最终值ax/bx
应该可以将e
打印到控制台:
ah = 0eH : teletype output command
al = 65H : The 'e' character.
bh = 00H : page zero.
bl = 00H : forground color (only for graphic modes).
cx/dx
的值应该无关紧要。有一个嵌入式BIOS替代品专门处理了cx = abcdH
的值,但是在这里这不可能成为问题。
因此,无论是否使用“愚蠢”代码,您的实际代码似乎都可以。但是,正如评论中指出的那样,从USB引导存在一个已知问题(如果您正在这样做)-看来USB引导过程会强制引导扇区的第一位保留某些磁盘属性信息(BIOS参数块或BPB)。这意味着您必须将代码移开,以便它可以正常运行。
This answer提供了所有详细信息,而要解决此问题,您可能只需将代码移到末尾即可,例如:
[bits 16]
[org 0x7c00]
jmp init
times 510 - ($ - $$) - (last - init) db 0 ; leave as much space as possible.
init:
jmp $ ; your actual code should go here.
last:
dw 0xaa55
这样,您最终将获得足够的空间用于USB启动以放置BPB(假设您的代码不太长):
1 [bits 16]
2 [org 0x7c00]
3 0000 E9F901 jmp init
4 0003 00<rept> times 510 - ($ - $$) - (last - init) db 0
5 init:
6 01FC EBFE jmp $
7 last:
8 01FE 55AA dw 0xaa55
当然,您可能只考虑将正确格式的自己 BPB放在此处。这样就不必将代码移到引导扇区末尾的麻烦了。