将32位程序转换为16位程序

时间:2013-04-14 08:29:14

标签: linux assembly gas

汇编程序为我的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”时会抛出错误

请帮忙

1 个答案:

答案 0 :(得分:2)

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

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

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