我对实模式寻址一定有一些基本的误解。我正在尝试设置一个功能以在实模式下通过 BIOS 中断打印文本。我正在使用在 DOSBox 下执行的 .com 文件测试代码。.text 部分结束于 0x1000(.com 文件中的 0x0F00)。所以假设我想打印该文本的第一个字母。
xor ebx, ebx
mov ecx, 1
mov ah, 10
mov al, ds:[0x1000]
int 0x10
那行得通,并打印出“ H”,因为我没有想象力。但是我不希望它只打印出同一个字母。我想传入一个指针,并且我想在打印更多文本时增加该指针。在这个阶段,我很高兴能从寄存器中读取偏移量。所以我做了以下改变。
mov edx, 0x1000
mov al, ds:[edx]
并且没有字符被打印。我尝试过使用 esi 和 edi 寄存器,结果相同。使用 lea edx,byte ptr [0x1000] 产生相同的结果。更糟糕的是,尝试使用 16 位等效项(dx、si、di)会导致程序挂起。我尝试过查看 .com 文件中的机器代码,但找不到任何明显错误的地方。
我正在使用自定义链接器脚本和 objcopy 调用使用 gcc 编译代码以生成 .com 文件。没有链接库,目标架构是 386。
任何帮助将非常感激。
编辑:完整列表。
方向.s
.intel_syntax
.global _printChar
_printChar:
push ebp;
mov ebp, esp;
xor edx, edx;
xor ebx, ebx;
xor eax, eax;
mov ecx, 1;
mov ah, 10;
mov edx, 0x1000;
mov al, ds:[edx];
int 0x10;
mov esp, ebp
pop ebp;
ret;
目录测试.c
asm
(
".code16gcc;\n" \
"call _dosmain;\n" \
"mov ah, 0x4C;\n" \
"int 0x21;\n"
);
#include "directio.h"
int dosmain(void)
{
printChar("Hello World!");
return 0;
}
com_mingw.ld
SECTIONS
{
. = 0x0100;
.text :
{
*(.text);
}
.data :
{
*(.data);
*(.bss);
*(.rodata);
}
_heap = ALIGN(4);
}
所有这些都使用以下命令行编译。
gcc -std=gnu99 -Os -nostdlib -m32 -masm=intel -march=i386 -ffreestanding -o dirTest.com -Wl,--nmagic,--script=com_mingw.ld dirTest.c directio.s
其次是
objcopy dirTest.com -O binary