Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 程序集BIOS调用不工作_Assembly_X86_Bootloader_Bios_X86 16 - Fatal编程技术网

Assembly 程序集BIOS调用不工作

Assembly 程序集BIOS调用不工作,assembly,x86,bootloader,bios,x86-16,Assembly,X86,Bootloader,Bios,X86 16,我正在使用一个简单的汇编代码片段,将BIOS作为引导加载程序的一部分,将字符打印到屏幕上。这是引导加载程序代码 [org 0x7c00] [bits 16] %include "a20_check.asm" mov ah, 0x0e mov al, 'H' int 0x10 times 510 - ($-$$) db 0 dw 0xaa55 这是a20_check.asm函数的代码,取自 问题似乎出现在最后一个标签中,请选中“a20退出”。如果我注释掉ret,则字符将打印到屏幕上。

我正在使用一个简单的汇编代码片段,将BIOS作为引导加载程序的一部分,将字符打印到屏幕上。这是引导加载程序代码

[org 0x7c00]

[bits 16]

%include "a20_check.asm"


mov ah, 0x0e
mov al, 'H'
int 0x10

times 510 - ($-$$) db 0
dw 0xaa55 
这是a20_check.asm函数的代码,取自

问题似乎出现在最后一个标签中,请选中“a20退出”。如果我注释掉
ret
,则字符将打印到屏幕上。否则,它不会打印


有人能给我解释一下这个问题吗?

如果您想一想自己对故障排除的描述,然后看看您是如何包含代码的,那么问题应该是显而易见的

  • 首先,包括检查A20行的代码
  • 该代码以
    ret
  • 接下来我们找到在屏幕上打印字符的代码
  • 最后我们有空填充
显然,
ret
将尝试使用当前位于
SP
的任何内容,并在那里切换执行路径。。。但你从未调用过任何东西,所以数据只是垃圾


删除
ret
允许它“跳转”到您的打印代码。

也许您应该在“mov ax,1”之后写一个跳转代码,跳转到“check_a20_______退出”最后一行之外的代码。我的理论是,您的代码不会从“je check_a20________退出”那一行跳转到“check__a20_________退出”这是导致代码紧跟在后面的“JE CHIGTA A20OXEXIT”执行,它也退出“CHIGTIOA 20X退出”,因为“CuffixA20x退出”只是一个标签,而不是C++中的函数。因此,RET语句在没有以前匹配跳转的情况下被调用。“指令。此代码运行在哪个H/W环境中?”?“mov ax,0”正试图通过使累加器寄存器为零来设置零标志。该代码正在使用使用i386体系结构的qemu仿真运行。@SahilSingh:该指令不会更改标志。@SahilSingh
je check\u a20\u exit
的标志由
cmp byte[es:di],0xFF
设置。“A20”的代码并不琐碎,除非你真的了解很多,否则不要试图猜测它是如何工作的。顺便说一句,
ax
init到0/1可以用无分支的方式重写:
sbb-ax,ax
inc-ax
除了您提到的在打印字符后,它们继续执行没有指定的代码(可能是内存漂移)。应该使用某种无限循环来避免这种情况。
[bits 16]


; Returns: 0 in ax if the a20 line is disabled (memory wraps around)
;          1 in ax if the a20 line is enabled (memory does not wrap around)

check_a20:
pushf
push ds
push es
push di
push si

cli

xor ax, ax ; ax = 0
mov es, ax

not ax ; ax = 0xFFFF
mov ds, ax

mov di, 0x0500
mov si, 0x0510

mov al, byte [es:di]
push ax

mov al, byte [ds:si]
push ax

mov byte [es:di], 0x00
mov byte [ds:si], 0xFF

cmp byte [es:di], 0xFF

pop ax
mov byte [ds:si], al

pop ax
mov byte [es:di], al

mov ax, 0
je check_a20__exit

mov ax, 1

check_a20__exit:
pop si
pop di
pop es
pop ds
popf

ret