NASM 中的片段?

Segments in NASM?

我一直在尝试将一个示例从 FASM(平面汇编器)复制到 NASM,但我没能做到,我试图理解 NASM 处理段(部分)的方式).

ormat mz
entry main:start
stack 100h

segment main
start:
  mov ax, text
  mov ds, ax

  mov dx, hello
  call extra:write_text

  mov ax, 4c00h
  int 21h

segment text
  hello db 'Hello world!', 24h

segment extra
write_text:
  mov ah, 9
  int 21h
  retf

FASM 生成一个 MSDOS exe 文件并在 DEBUG 中加载它我看到以下内容:

0D9D:0000 B89F0D            MOV     AX,0D9F
0D9D:0003 8ED8              MOV     DS,AX
0D9D:0005 BA0000            MOV     DX,0000
0D9D:0008 9A0000A00D        CALL    0DA0:0000
0D9D:000D B8004C            MOV     AX,4C00
0D9D:0010 CD21              INT     21

如您所见,FASM 创建了段并将 CALL 设置为远调用。 extra 被有效地放置在一个单独的段中。数据段也在一个单独的段中。

我尝试在 NASM 中做这个例子:

section code
..start:
  mov ax, seg hello
  mov ds, ax

  mov dx, hello
  call extra:write_text

  mov ax, 4c00h
  int 21h

section data
  hello db "Hello World!", 24h

section extra
write_text:
  mov ah, 9
  int 21h
  retf

section stack class=stack
  resb 100h

并且link与wlink一起使用这个link文件:

system  dos
option  map
name    seg2.exe
file    seg2.obj

生成的代码不同:

0D9D:0000 B89D0D            MOV     AX,0D9D
0D9D:0003 8ED8              MOV     DS,AX
0D9D:0005 BA1200            MOV     DX,0012
0D9D:0008 9A1F009D0D        CALL    0D9D:001F
0D9D:000D B8004C            MOV     AX,4C00
0D9D:0010 CD21              INT     21
0D9D:0012 48                DEC     AX
0D9D:0013 65                GS:     (unused)
0D9D:0014 6C                INSB
0D9D:0015 6C                INSB
0D9D:0016 6F                OUTSW
0D9D:0017 20576F            AND     [BX+6F],DL
0D9D:001A 726C              JB      0088
0D9D:001C 642124            AND     FS:[SI],SP
0D9D:001F B409              MOV     AH,09

如您所见,write_text 与代码的其余部分(显然还有数据段)在同一段中,但它并没有像我想的那样放在单独的段中。

我是不是漏掉了什么?有什么方法可以将代码实际放在单独的段中吗?任何关于正在发生的事情或如何实现这些的帮助、指导或解释将不胜感激!

是的,我在 MASM 中尝试过,同样的事情发生了,FASM 是唯一具有这种超能力的吗?

谢谢!

您想要的是对内存模型的支持,NASM lacks,它将段间传输视为 NEAR,程序员负责编码必要时 CALL FAR 指令.

不,FASM 不是唯一知道内存模型的汇编器。这是为 €ASM

量身定制的程序
|                          |seg4 PROGRAM Format=MZ,Model=LARGE,Entry=start
|[main]                    |[main] SEGMENT Purpose=CODE
|0000:                     |start:
|0000:B8{0000}             |  mov ax,PARA# [text]
|0003:8ED8                 |  mov ds, ax
|0005:BA[0000]             |  mov dx, hello
|0008:9A[0000]{0000}       |  call write_text
|000D:B8004C               |  mov ax, 4c00h
|0010:CD21                 |  int 21h
|0012:                     |
|[text]                    |[text] segment Purpose=DATA
|0000:48656C6C6F20776F726C~|  hello db 'Hello world!', 24h
|[extra]                   |[extra] segment Purpose=CODE
|0000:                     |write_text:
|0000:B409                 |  mov ah, 9
|0002:CD21                 |  int 21h
|0004:CB                   |  retf
|[stack]                   |[stack] SEGMENT Purpose=STACK
|0000:....................~|   DW 100h * BYTE
|                          | ENDPROGRAM
|        **** ListMap "seg4.exe",groups=4,segments=4,entry=[main]:00000000h,stack=[stack]:00000100h
|        [main],RVA=00000000h,size=00000012h=18,group [main]
|          [main],RVA=00000000h,size=00000012h=18,width=16,align=0010h,purpose=CODE
|        [text],RVA=00000020h,size=0000000Dh=13,group [text]
|          [text],RVA=00000020h,size=0000000Dh=13,width=16,align=0010h,purpose=DATA
|        [extra],RVA=00000030h,size=00000005h=5,group [extra]
|          [extra],RVA=00000030h,size=00000005h=5,width=16,align=0010h,purpose=CODE
|        [stack],RVA=00000040h,size=00000100h=256,group [stack]
|          [stack],RVA=00000040h,size=00000100h=256,width=16,align=0010h,purpose=STACK