c - 如何修复“从引导加载程序跳转到 C 代码时出现无限循环错误”
问题描述
我实际上是在尝试运行 C 代码来编写我的操作系统内核来研究操作系统是如何工作的。当引导加载程序跳转到我的 C 代码时,我陷入了这个无限循环。我应该如何防止这个错误
尽管我的引导加载程序工作正常,但当我的引导加载程序跳转到用 C 作为a.COM
程序编写的内核代码时,问题就出现了。主要的是,尽管代码只能运行一次,但虚拟代码只是不断地一次又一次地打印一个字符。似乎主代码被一次又一次地调用。这是程序startpoint.asm
集头和bootmain.cpp
文件的代码。
这是startpoint.asm
最初链接时使用的代码,以便可以自动调用代码。(写在MASM中)
注意:代码是在地址加载的2000H:0000H
。
;------------------------------------------------------------
.286 ; CPU type
;------------------------------------------------------------
.model TINY ; memory of model
;---------------------- EXTERNS -----------------------------
extrn _BootMain:near ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------
.code
main:
jmp short start ; go to main
nop
;----------------------- CODE SEGMENT -----------------------
start:
cli
mov ax,cs ; Setup segment registers
mov ds,ax ; Make DS correct
mov es,ax ; Make ES correct
mov ss,ax ; Make SS correct
mov bp,2000h
mov sp,2000h ; Setup a stack
sti
; start the program
call _BootMain
ret
END main ; End of prog
代码bootmain.cpp
extern "C" void BootMain()
{
__asm
{
mov ah,0EH
mov al,'G'
int 10H
}
return;
}
编译和链接器命令如下:
编译代码bootmain.cpp
:
CL.EXE /AT /G2 /Gs /Gx /c /Zl bootmain.cpp
编译代码startpoint.asm
:
ML.EXE /AT /c startpoint.asm
将它们链接起来的代码(按保留顺序):
LINK.EXE /T /NOD startPoint.obj bootmain.obj
预期输出:
G
实际输出:
GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
解决方案
仔细看看结尾start
。
start
永远不会被调用——它被直接跳转到,它自己设置堆栈。返回时_BootMain
,栈为空;ret
末尾的将从start
堆栈末尾弹出垃圾数据并尝试跳转到它。如果该内存包含零,则程序流程将返回到main
.
你需要设置一些特定的东西在_BootMain
返回后发生。如果您只是希望系统在执行后挂起_BootMain
,请插入一个无限循环(例如jmp .
)到结尾start
而不是错误的ret
.
或者,考虑让您的引导加载程序设置堆栈本身和call
COM 可执行文件。当它返回时,引导加载程序可以采取适当的措施。
推荐阅读
- google-chrome - 如何针对 HSTS 标头检查 wesbites 列表?
- html - 如何在 Angular 2+ 中显示 AngularJS
- flutter - 小部件中的 Flutter if 语句
- cmake - 使用未声明的标识符“_ISspace”
- javascript - 我想创建一个变量来防止用户重复点击,但它不起作用
- ignite - 我们可以在 Ignite Key-Value Cache 中存储复杂的 POJO 对象吗?
- java - Android - 支付成功时Paygate支付网关重定向错误
- c++ - 在 UNICODE_STRING 中搜索字符
- python - 使用 UDP 套接字在 python 中发送连续数据
- actions-on-google - Surface Capabilities——区分智能显示器和移动设备