【问题标题】:What code skeleton should I use for Intel 8086 DOS assembly?我应该为 Intel 8086 DOS 程序集使用什么代码框架?
【发布时间】:2013-12-14 10:33:33
【问题描述】:

学习了 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

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

【问题讨论】:

  • 你可以使用旧的方式就好了。第二个示例的级别稍高,但非常可选。我自己从来没有使用过它,但是当你编写一个更大的应用程序时它会很有用。并且能力取决于您的汇编编译器 - 差异很大在于编译器,而不是 CPU 架构或指令集。
  • @Luaan - 我明白了。在这种情况下,我会尽量坚持第一个示例样式,以免一开始就让自己太困惑。谢谢你:)
  • 你应该参考“Richard Blum 的专业汇编语言”一本好书。还有一个基本链接......wiki.osdev.org/Assembly
  • 第一个例子使用了简化的指令。第二个使用详细指令。 (第二个也是大模型,但第一个是小模型。)较旧的代码使用详细指令,因为 1992 年还没有简化指令。
  • @Straightfw :有一点是确定的:RaymondChen 知道他在说什么。如果您有疑问,请查看他的博客“The Old New Thing”,或同名书籍。

标签: assembly x86 dos x86-16


【解决方案1】:

这在很大程度上取决于您所针对的操作系统(或 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) 命令行中定义源 (org)。

我还有an example targetting raw x86 BIOSanother one (bootsector for blocklists)another one (bootsector for *.tar archives),如果你有兴趣的话;但是它们需要不同的来源,并且即使它们只使用 16 位模式,它们也需要 i386 CPU。

你不能那样做 *.EXE 文件。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多