Gcc C交叉编译器中的分段内存模型

Gcc C交叉编译器中的分段内存模型,gcc,x86-16,inline-assembly,osdev,codesourcery,Gcc,X86 16,Inline Assembly,Osdev,Codesourcery,我正在做一些关于8086实模式的工作。我习惯于在汇编程序中完成这项工作,但我想尝试一下C编译器。在我看来,编译器假定所有段寄存器都具有相同的值。我的情况并非如此SS为0x4C0,而DS=ES=CS=0x800 因此,下面的代码在编译时会生成代码,而不考虑SS DS的事实 [来源:] 编译时,赋值生成:[完整源:] 因为没有明确提到SS,所以DS将由汇编程序承担 如上所述,在我的例子中,SSDS,因此AL现在有一个来自错误地址的值 MOV AL,DS:[BX+SI-0x11]MOV AL,SS:[

我正在做一些关于8086实模式的工作。我习惯于在汇编程序中完成这项工作,但我想尝试一下C编译器。在我看来,编译器假定所有段寄存器都具有相同的值。我的情况并非如此SS为0x4C0,而DS=ES=CS=0x800

因此,下面的代码在编译时会生成代码,而不考虑SS DS的事实

[来源:]

编译时,赋值生成:[完整源:]

因为没有明确提到SS,所以DS将由汇编程序承担

如上所述,在我的例子中,SSDS,因此AL现在有一个来自错误地址的值

MOV AL,DS:[BX+SI-0x11]MOV AL,SS:[BX+SI-0x11]

我尝试过的编译器

1。GCC版本6.2.0(Sourcery CodeBench Lite 2016.11-64)

链接器文件如下所示:

OUTPUT_FORMAT(binary)
SECTIONS
{
    . = 0x0;
    .text :
    {
        *(.text);
    }
    .data :
    {
        *(.data);
        *(.bss);
        *(.rodata);
    }
    _heap = ALIGN(4);
    /DISCARD/ : 
    {
         *(.eh_frame)
    }
}
2。Bruce的C编译器[与BCC一起使用的完整源代码]

更新: 我试过斯莫尔。这里,编译器再次假设SS=DS

3。较小的C[来源]


两个编译器中的结果大致相同从堆栈读取时,没有编译器显式指定SS。问题是有没有一种方法可以告知编译器有关约束的情况,我是否做错了什么。

您是否尝试过watcom或borland编译器?Watcom早就把它扔到了篱笆上/公开了他们的套件。他们有16位多模型编译器。我不知道博兰兹州的情况;但是,如果你能找到一个图像,那么在qemu下运行它的速度可能比在真正的机器上运行更快

他们支持多种记忆模型;您可能需要的是紧凑型:16位代码指针,32位数据指针。此处有一个引用:

即使这样做了,根据您的尝试,最终可能会出现这些称为段修复的奇怪情况,这允许在1mb地址空间内有限地重新定位程序。这些东西很快就老了

为了让生活更轻松,你可以使用一个小模型(它可以生成真实的图像);并使所有外部数据由显式远指针引用。这是一种怪诞的黑客行为,你最终可以:

const char far const * const far *p;
不是开玩笑。80年代和90年代,C和C++之间出现了一场赛马,以创建最有编程语言的恶意语法。显然C++赢得了,但是ISO-C委员会拒绝认输,让世界每隔几年变得疯狂一点。
一点建议:将机器翻转到32位模式,并使用一些合理的工具。

评论不用于进一步讨论;此对话已结束。谢谢您的回复。我试过打开Watcom,它可以工作(使用-zu选项)。然而,我决定在汇编中编写内核和驱动程序(就像原来的86-DOS一样)。我可以在任何8086 C交叉编译器中编写应用程序,因为内核在调用应用程序(微型模型)时会确保SS=DS。这就是我现在的决定。我现在有点明白了,写一个受保护模式的操作系统会容易得多,但是你看,这是我第一次做操作系统开发工作,所以我希望它能接近原始版本,而且我希望当我老的时候,我可以吹嘘一下:)
ia16-elf-gcc -Wall main.c -o main.com -T main.ld
OUTPUT_FORMAT(binary)
SECTIONS
{
    . = 0x0;
    .text :
    {
        *(.text);
    }
    .data :
    {
        *(.data);
        *(.bss);
        *(.rodata);
    }
    _heap = ALIGN(4);
    /DISCARD/ : 
    {
         *(.eh_frame)
    }
}
bcc -ansi -0 -W -c main.c -o main.o
ld86 -d main.o -o main.com -T000
    smlrc -seg16 -Wall main.c main.s
    nasm -f bin main.s -o main.com
const char far const * const far *p;