首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GNU汇编程序指令.code16的目的是什么?

GNU汇编程序指令.code16的目的是什么?
EN

Stack Overflow用户
提问于 2020-02-02 11:25:16
回答 1查看 1K关注 0票数 2

我不理解.code16或其他.code*指令的实际用法。我从this question on StackOverflow的答案中了解到,

当某人在其程序集代码中定义.code16并执行以下操作时:

代码语言:javascript
运行
复制
$ gcc -c -m32 -o main.o main.s

它忽略.code16,输出程序集将在32位平台上运行。如果有人没有指定-m标志,它似乎将为gcc配置的标志作为默认设置,这取决于主机。因此,总之,.code*指令总是被-m标志所忽略和取代。

如果我理解错了,请有人纠正我,我使用.code16的情况是什么,因为我总是可以定义使用-m16.code*无论如何都会被忽略,这取决于目标模式。

.code16 (或其他人)是否只打算在数据不能放入16位寄存器时抛出错误,否则,它们将保持休眠状态吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-02 11:50:56

通常使用.code16.code32.code64的唯一原因是当您希望在同一个文件中拥有不同模式的机器代码时,在内核或引导程序中。例如,以实模式(.code16)启动的引导加载程序可以启用保护模式和跳远(ljmp)到32位代码段。您可能希望在这段代码之前使用.code32

如果这不是你要做的,就不要用它们。

在其他情况下,使用它们只会让你自投罗网,并将16位的机器代码放入32位或64位的ELF可执行文件中,这样您就可以获得运行时故障,而不是在构建时捕获错误。(例如,因为push %eax在64位模式下无效)。不要将.code32放在32位程序的顶部;使用一个注释,上面写着与gcc -m32汇合。

这些指令告诉汇编程序,当它解码这些指令时,CPU将采用什么模式。因此,它知道默认操作数大小和地址大小,以及使用32位或16位寄存器的指令是否需要前缀。

例如,mov %eax, (%ecx)以32位模式组装到89 01 .

但是在.code16之后,它组装成67 66 89 01

如果然后将其反汇编为32位机器代码,则为67 66 89 01 mov %ax, (%bx,%di) (因为在16位、32位和64位模式下,内存操作数的ModRM是不同的)。

通常不会手动使用.code16。您可以使用gcc -m16 foo.c让GCC在文件顶部插入.code16gcc,这样您就可以以16位模式运行它,即使它仍然使用32位操作数大小和地址大小(需要一个386兼容的CPU)。

如果您希望将32位或16位机器代码作为数据包含在普通64位程序中,例如,您的程序可以将其写入文件或修改正在运行的进程,您也可以使用.code32.code16

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60025609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档