我应该使用什么代码框架来进行Intel 8086 DOS汇编?

8

学习了Intel 8080结构之后,我现在正在尝试学习Intel 8086以及这里的程序布局。现在,即使看基本的例子也是相当令人畏惧的,更糟糕的是,我无法理解我遇到的两种写8086代码的不同方式。也就是说,有时我看到:

.model small
.stack 100h
.code

start:

mov dl, ‘a’ ; store ascii code of ‘a’ in dl
mov ah, 2h ; ms-dos character output function
int 21h ; displays character in dl register
mov ax, 4c00h ; return to ms-dos
int 21h

end start

我也发现:

Progr           segment
                assume  cs:Progr, ds:dataSeg, ss:stackSeg

start:          mov     ax,dataSeg
                mov     ds,ax
                mov     ax,stackSeg
                mov     ss,ax
                mov     sp,offset top


            mov     ah,4ch
            mov     al,0
            int     21h
Progr           ends

dataSeg            segment

dataSeg            ends

stackSeg          segment
                dw    100h dup(0)
top     Label word
stackSeg          ends

end start

显然,我知道这两个做的事情非常不同,但令我困惑的是它们的一般语法有多么不同。在后者中,我们有一些"segment assume",而在前者中只有.model、.stack和.code(有时还有.data,据我发现)。它们有区别吗?我可以随意选择哪一个更适合我吗?前者看起来更容易理解和更清晰,但我可以用它来替代后者吗?

2
你可以继续使用旧的方法,没有问题。第二个例子稍微高级一些,但是非常可选。我自己从来没有用过它,但在编写较大的应用程序时可能会有用。而能力取决于汇编编译器 - 差异很大程度上在于编译器,而不是 CPU 架构或指令集。 - Luaan
你应该参考Richard Blum的《专业汇编语言》这本好书。此外,这里有一个基础链接...http://wiki.osdev.org/Assembly - Sam
6
第一个例子使用简明指令,第二个例子使用冗长指令(第二个也是大模型,但第一个是小模型)。旧的代码使用冗长指令,因为在1992年时还没有简明指令。 - Raymond Chen
@Straightfw :) 祝你好运!欢迎来到8086 :) - Sam
1
@Straightfw:有一件事是肯定的:RaymondChen 知道他在说什么。如果你怀疑,可以查看他的博客《The Old New Thing》,或同名书籍。 - Joe Z
显示剩余3条评论
1个回答

3
这在很大程度上取决于您的操作系统目标(或BIOS或裸机)、目标可执行文件格式和使用的汇编器。
您发布的第一个示例是针对MS-DOS .COM程序的,第二个示例是针对MS-DOS .EXE程序的,我假定两者都使用了Microsoft®汇编器。
如果您想使用GNU汇编器(例如在MirBSD或GNU/Linux上)来针对i8086 MS-DOS .COM程序,可以使用以下内容:
        .intel_syntax noprefix
        .code16
        .text

        .globl  _start
_start: mov     ah,9
        mov     dx,offset msg
        int     0x21
        /* exit(0); ← this is a comment */
        mov     ax,0x4C00
        int     0x21

msg:    .ascii  "Hello, World!\r\n$"

使用以下命令编译此文件(hw.S):

$ gcc -c -o hw.o hw.S
$ ld -nostdlib -Ttext 0x0100 -N -e _start -Bstatic --oformat=binary -o hw.com hw.o

我在MirBSD/i386下的DOSBOX中测试了结果,并通过hexdump查看其是否正确。

与其他解决方案不同,您不需要在汇编文件中定义原点(org),而是在链接器(ld)命令行中定义,如此处所示。

如果您感兴趣,我还有一个针对原始x86 BIOS的示例另一个(用于块列表的引导扇区)以及另一个(用于*.tar归档的引导扇区),它们需要不同的起点,并且尽管它们仅使用16位模式,但需要i386 CPU。

您无法以这种方式创建*.EXE文件。

ELKS也是一个有趣的i8086目标,但我还没有做太多关于它的工作。确保你获得一个足够新的GNU as版本,以了解模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接