我应该为Intel 8086 DOS程序集使用什么代码框架?

在学习了英特尔8080结构之后,我现在正在尝试学习英特尔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

显然,我知道这两个做了很多不同的事情,但令我感到困惑的是一般语法有多么不同.在后者我们有一些“段假设”,而在前者它只是.model,.stack和.code(有时.data,从我发现的).有什么区别吗?我可以选择哪一个更适合我吗?前者看起来更容易理解和清晰,但我可以使用它而不是后者吗?

这主要取决于您所针对的操作系统(或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中查看它,看它是否正确.

与其他解决方案相比,您不在此处定义程序集文件中的origin(org),而是在链接器(ld)命令行上定义.

如果您有兴趣,我还有an example targetting raw x86 BIOSanother one (bootsector for blocklists)another one (bootsector for *.tar archives);虽然它们需要不同的起源,但它们需要i386 CPU,即使它们仅使用16位模式.

你不能这样做* .EXE文件.

ELKS也是一个有趣的i8086目标,但我还没有做太多.确保你获得GNU作为新版本足以知道.intel_syntax noprefix模式.

相关文章
相关标签/搜索