14

我正在编写实模式函数,它应该是带有堆栈帧等的普通函数,但它应该使用 %sp 而不是 %esp。有什么办法吗?

4

4 回答 4

8

-m16GCC 5.2.0(和可能的更早版本)支持带有标志的 16 位代码生成。但是,代码几乎肯定会依赖于 32 位处理器功能(例如 32 位宽寄存器),因此您应该仔细检查生成的程序集。

man页面:

-m16 选项与 -m32 相同,只是它在程序集输出的开头输出“.code16gcc”程序集指令,以便二进制文件可以在 16 位模式下运行。

于 2015-10-08T18:02:05.813 回答
7

首先,gcc可以编译16bit的代码,因为linux内核是通过realmode到protectmode,所以甚至可以编译16bit的c代码。

然后,GCC >= 4.9 支持 -m16 选项,clang >= 3.5

gcc 将忽略 asm(".code16"),你可以通过 -S 输出 #APP #NO_APP 周围的汇编代码看到它

linux 内核执行使用code16gcc.h(只有.code16gcc)编译16位c的技巧直接传递给gcc编译参数。请参阅Build 16-bit code with -m16 where possible , 如果您直接放入 asm(".code16gcc") ,请参阅 linux kernel build Makefile ,请参阅 Writing 16-bit Code,它不是真正的 16bit 代码,, , , , , , ,

callretenterleavepushpoppushapopa, pushf, 和popf指令默认为 32 位大小

于 2018-12-16T12:03:31.483 回答
6

GCC does not produce 8086 code. The GNU AS directive .code16gcc can be used to assemble the output of GCC to run in a 16-bit mode, put asm(".code16gcc") at the start of your C source, your program will be limited to 64Kibytes.

On modern GCC versions you can pass the -m16 argument to gcc which will produce code to run in a 16-bit mode. It still requires a 386 or later.

于 2013-09-28T06:37:50.240 回答
5

据我所知,GCC 不支持为 16 位 x86 生成代码。对于遗留引导加载程序和类似目的,您应该用汇编语言编写一个小存根,以将 cpu 置于 32 位模式并将执行传递给 32 位代码。出于其他目的,您真的不应该编写 16 位代码。

于 2013-09-27T16:33:51.487 回答