3

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

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

[来源:这里]

uint8 ch;
void main()
{
    uint8 hexchars[] = {'0','1','2','3','4','5','6','7','8','9','A','B',
                        'C','D','E','F'};
    uint8 i = 0;
    ch = hexchars[i];
}

编译后,作业产生:[完整来源:此处]

// ch = hexchars[i];
00000156  8A46FF            mov al,[bp-0x1]        ; 'i' is at [BP - 0x1]
00000159  30E4              xor ah,ah
0000015B  89C7              mov di,ax
0000015D  89EE              mov si,bp
0000015F  89FB              mov bx,di
00000161  8A40EF            mov al,[bx+si-0x11      ; 'hexchars[0] is at [BP - 0x11]
00000164  A28401            mov [0x184],al          ; 'ch' is at location 0x184

因为没有明确提到 SS,所以 DS 将由汇编程序假定。

如上所述,在我的情况下SS <> DS,因此 AL 现在具有来自错误地址的值。

移动铝,DS:[BX + SI - 0x11] <>移动铝,SS:[BX + SI - 0x11]

我尝试过的编译器

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

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)
    }
}

2. Bruce 的 C 编译器[此处使用 BCC 的完整源代码]

bcc -ansi -0 -W -c main.c -o main.o
ld86 -d main.o -o main.com -T000

更新: 尝试了 SmallerC。这里再次编译器假设 SS = DS。

3. 较小的 C [来源]

    smlrc -seg16 -Wall main.c main.s
    nasm -f bin main.s -o main.com

结果在两个编译器中或多或少相同。从 stack 读取时,没有编译器明确指定 SS。问题是有一种方法可以通知编译器有关约束的信息,我是不是做错了什么。

4

1 回答 1

1

您是否尝试过 watcom 或 borland 编译器?Watcom 把它扔在栅栏上/很久以前就开源了他们的套件。他们有 16 位多模型编译器。我不知道borlands的状态;但是如果你能找到一个图像,你可能在 qemu 下运行它比在真机上运行它更快。

他们支持多种内存模型;您可能想要的是紧凑的:16 位代码指针,32 位数据指针。这里有一个参考:What the ....

即使你已经完成了,取决于你尝试做什么,你最终可能会得到这些称为段修复的奇怪东西,它允许在 1mb 地址空间内有限地重新定位程序。这些很快就会变老。

为了让生活更轻松,您可以使用一个微型模型(生成真实图像);并使所有外部数据都被显式远指针引用。这是一个怪诞的 hack,你最终会得到:

const char far const * const far *p;

不是开玩笑。80 年代和 90 年代见证了 C 和 C++ 之间的赛马,因为它们创建了对程序员最敌对的语法。显然 C++ 赢了,但 ISO-C 委员会拒绝认输,每隔几年就会让世界变得更加疯狂。

一点建议:将机器切换到 32 位模式,并使用一些理智的工具。

于 2019-08-07T23:48:00.350 回答