我试图为我的旧286建立一个小的 Bootstrap /程序。我开始用fasm做这件事,很快就厌倦了编写汇编。所以我想用c来写它,但是针对286的c工具链的选择似乎很小。我选择了Open Watcom 1.9。到目前为止,我设法得到一些东西来编译,但输出是坏的,我不知道为什么。
init.asm,编写为兼容watcoms汇编程序,初始化寄存器,跳转到c函数kernelMain,并提供一个简单的打印函数:
.code INIT
extern kernelMain_ : proc
org 7c00h
;export functions
PUBLIC initMain
PUBLIC _print
initMain:
;init stack to use the 30kb before this boot sector
;init other segment registers
mov bp,7C00h ; stack base pointer
xor ax,ax ; ax = 0
mov ds,ax ; data segment = 0
mov es,ax ; extra segment
mov ss,ax ; stack segment = 0
mov sp,bp ; stack pointer = 7C00h
jmp kernelMain_
;void __cdecl print(char* message, unsigned char length);
_print:
pop si ; message
pop cx ; length
printLoop: ; print string which is at adress si with length cx
mov ah,0Eh ; TTY output function number
mov bh,0 ; page 0
mov bl,01h ; foreground color
lodsb ; loads byte from [si] into al and advances pointer in si by 1
int 10h ; BIOS video interrupt, write byte to screen
loop printLoop ; loop till message is printed
ret
end
字符串
test.c,包含kernelMain函数:
extern void __cdecl print(char* message, unsigned short length);
void kernelMain(void)
{
print("this is a test", 14);
}
型
这就是我用来建造它的东西
wasm -2 -ms init.asm
wcc -2 -d0 -wx -ms -s -zl test.c
wlink file init.obj file test.obj format raw bin name test.bin option NODEFAULTLIBS,verbose,start=initMain ORDER clname CODE segment INIT
型
结果的二进制文件是~ 32 KB,而不是预期的几个字节,因为链接器解释org指令实际上用代码之前的0字节填充所有内容。在代码完全破坏代码之前移除0填充。它不打印任何东西。删除org指令会给我执行和打印的代码,但它也会在测试消息之前打印出一些随机垃圾
有人能帮帮我吗?
1条答案
按热度按时间tp5buhyn1#
感谢评论者,我现在得到了我想要的。
修复:
1.放弃asm从c代码中分离的想法,只使用c与内联汇编
1.从这里升级到开放watcom 2.0测试版https://github.com/open-watcom/open-watcom-v2/releases(当前版本包含版本和安装程序)
试验c:
字符串
buildtest.bat:
型
这给了我一个原始的二进制链接地址0x7c00。
要创建一个可写入软盘(或被虚拟机用作软盘)的可引导扇区,您必须将文件的其余部分填充为510字节长度,并添加0x55 0xAA作为最后2个字节(总共512个字节),将其标记为可引导扇区。
备注:分开的asm和c的东西可能仍然会像预期的那样工作,如果作者(我)实际上可以编写正确的汇编