我正在编写实模式函数,它应该是带有堆栈帧等的普通函数,但它应该使用 %sp 而不是 %esp。有什么办法吗?
4 回答
-m16
GCC 5.2.0(和可能的更早版本)支持带有标志的 16 位代码生成。但是,代码几乎肯定会依赖于 32 位处理器功能(例如 32 位宽寄存器),因此您应该仔细检查生成的程序集。
从man
页面:
-m16 选项与 -m32 相同,只是它在程序集输出的开头输出“.code16gcc”程序集指令,以便二进制文件可以在 16 位模式下运行。
首先,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 代码,, , , , , , ,call
ret
enter
leave
push
pop
pusha
popa
, pushf
, 和popf
指令默认为 32 位大小
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.
据我所知,GCC 不支持为 16 位 x86 生成代码。对于遗留引导加载程序和类似目的,您应该用汇编语言编写一个小存根,以将 cpu 置于 32 位模式并将执行传递给 32 位代码。出于其他目的,您真的不应该编写 16 位代码。