如何告诉GCC为实模式生成16位代码

use*_*423 11 c assembly gcc inline-assembly x86-16

我正在编写实模式函数,它应该是具有堆栈帧的正常函数,但是它应该使用%sp而不是%esp.有办法吗?

lin*_*ina 7

GCC 5.2.0(以及可能的早期版本)支持使用该-m16标志生成16位代码.但是,代码几乎肯定会依赖于32位处理器功能(例如32位宽的寄存器),因此您应该仔细检查生成的程序集.

man页面:

-m16选项与-m32相同,除了它在汇编输出的开头输出".code16gcc"汇编指令,以便二进制可以在16位模式下运行.

  • 但不要忘记 Michael Petch 提到的内容:/sf/ask/1333895321/#comment53870969_19064127 这仅使用 16 位前缀版本的指令,而不是裸 16 位代码。 (2认同)

Tim*_*win 6

GCC 不产生 8086 代码。GNU AS 指令.code16gcc可用于汇编 GCC 的输出以在 16 位模式下运行,放在asm(".code16gcc")C 源代码的开头,您的程序将被限制为 64 KB。

在现代 GCC 版本中,您可以传递-m16参数,gcc该参数将生成以 16 位模式运行的代码。它仍然需要 386 或更高版本。

  • 使用 .code16gcc(我仍然不确定是否可以将其称为稳定功能)将生成在 16 位实模式下运行的代码,但是它使用仅在 386+ 上可用的指令前缀。这意味着如果您的目标是 8086/8088(真实硬件或模拟器),那么代码可能无法正常工作。如果您打算引导进入 32 位保护模式,则编写一个小的 16 位汇编程序存根来设置所有内容,进入保护模式,然后调用作为程序开始的 32 位“C”函数。 (9认同)

R..*_*R.. 5

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


Luk*_*ung 5

首先,gcc可以构建16位代码,因为linux内核经历了实模式转换为保护模式,因此它甚至可以构建16位c代码。

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

gcc将忽略asm(“。code16”),您可以通过-S看到它,并输出#APP #NO_APP包围的汇编代码

,Linux内核执行使用code16gcc.h(仅具有.code16gcc)编译16位c语言的技巧直接传递给gcc编译参数。看到与-m16生成16位代码在可能的情况,也看到了Linux内核构建的Makefile

,如果你直接把ASM(“code16gcc”),看到写16位代码,这不是真正的16位代码,callretenterleavepushpoppushapopapushfpopf指令默认为32位大小