0

汇编程序为我的 16 位代码 movzbw (%ax) 抛出错误,%ax 错误:`(%ax)' 不是有效的基础/索引表达式

但以下指令对 32 位代码生成有效。movzbl (%eax), %eax

环境:处理器:英特尔(x86) 汇编器:“GNU AS” 操作系统:“Linux” 目的:在编写一个非常简单的引导加载程序时,将“Hello, World”打印到屏幕上,我试图将一个字符串传递给一个函数并然后逐字节遍历,然后打印。

我可以用来避免编写 16 位实模式代码时出错的等效指令是什么?

更多信息:下面是我试图在“16 位 GNU AS”汇编器中模拟的 C 代码

void _prints(char*);


int main(void)
{
   char* mess = "hello";
   _prints(mess);
   return 0;
}

void _prints(char* str)
{
   while(*str)
   {
      ++str;
   }
}

注意:在尝试使用命令“gcc -S test.c”生成程序集文件时,我在 _prints 函数中看到指令“movzbl (%eax), %eax”。我想使用相同的汇编程序模拟 16 位实模式代码,但在使用“movzbw (%ax), %ax”时会引发错误

请帮忙

4

1 回答 1

2

在实模式下,(%ax)( [ax]) 不是有效的间接寻址方法。你必须使用%bp寄存器。我建议你拿起英特尔(或 AMD)处理器手册,像我一样从前到后阅读第 2 卷(适用于英特尔)。

如果您只是删除e以模拟真实模式,则没有必要。您的程序不会编译为 16 位可执行文件。它仍然是 32 或 64 位可执行文件,带有gcc. 生成 16-but 可执行文件的唯一方法是使用 OpenWatcom。即使这样,也没有必要编写 16 位程序。它们很慢,并且在处理器上的真实模式和保护模式(更改执行线程)之间的切换很昂贵。

正如您所提到的,这是针对引导加载程序的,您不能像这样编写引导加载程序。您必须手动编写程序集。我知道没有例外。

于 2013-04-14T08:34:37.040 回答