Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly “英特尔8086 DOS汇编”应使用什么代码框架?_Assembly_X86_Dos_X86 16 - Fatal编程技术网

Assembly “英特尔8086 DOS汇编”应使用什么代码框架?

Assembly “英特尔8086 DOS汇编”应使用什么代码框架?,assembly,x86,dos,x86-16,Assembly,X86,Dos,X86 16,在学习了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 2

在学习了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)。有什么区别吗?我能选择哪一个更适合我吗?前者看起来更容易理解和更清晰,但我能用它代替后者吗

这在很大程度上取决于所针对的操作系统(或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
):

我在MirBSD/i386下的DOSBOX中测试了结果,并在hextump中查看了它,以确定它是正确的

与其他解决方案不同,您不在程序集文件中定义原点(org),而是在链接器(ld)命令行中定义原点(org)

如果你感兴趣的话,我还有;虽然它们需要不同的来源,但它们需要i386 CPU,即使它们只使用16位模式

你不能用那种方式处理*.EXE文件


麋鹿也是一个有趣的i8086目标,但我还没有做太多。请确保您获得的GNU版本足够新,足以了解
.intel\u语法noprefix
模式。

您可以使用旧的方式。第二个示例的级别稍高,但非常可选。我自己从来没有使用过它,但是当您编写更大的应用程序时,它会很有用。这些能力取决于你的汇编程序编译器——不同之处在于编译器,而不是CPU架构或指令集。@Luaan-我明白了。在这种情况下,我将尽量保留第一个示例样式,以避免在开始时过于混淆自己。谢谢:)你应该参考《Richard Blum的专业汇编语言》这本好书。。这里还有一个基本链接。。。第一个示例使用简化指令。第二种方法使用冗长的指令。(第二个也是大模型,但第一个是小模型。)较旧的代码使用冗长的指令,因为简化指令在1992年不可用。@Straightfw:有一点是肯定的:RaymondChen知道他在说什么。如果你有疑问,可以查阅他的博客“新旧事物”,或是同名的书。
$ gcc -c -o hw.o hw.S
$ ld -nostdlib -Ttext 0x0100 -N -e _start -Bstatic --oformat=binary -o hw.com hw.o