汇编程序为我的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”时会抛出错误
请帮忙
答案 0 :(得分:2)
在实模式下,(%ax)
([ax]
)不是有效的间接寻址方法。您必须使用%bp
寄存器。我建议你拿起英特尔(或AMD)处理器手册,并像我一样从正面到背面阅读第2卷(英特尔)。
如果你只是删除e
来模拟真实模式,则没有必要。您的程序将无法编译为16位可执行文件。它仍然是带有gcc
的32位或64位可执行文件。生成16个但可执行文件的唯一方法是使用OpenWatcom。即使这样, no 也需要编写16位程序。它们很慢,并且在处理器上实际和受保护模式(更改执行线程)之间的切换是昂贵的。
正如您所提到的,这是针对引导加载程序的,您无法编写这样的引导加载程序。你必须手工编写程序集。没有我所知道的例外。