【发布时间】:2021-12-14 10:46:36
【问题描述】:
我一直试图将一个示例从 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
并使用此链接文件与 wlink 链接:
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 是唯一拥有这种超能力的人吗?
谢谢!
【问题讨论】:
-
我认为链接器只是在可能的情况下合并段。可以提供一个选项来防止这种情况发生。
标签: assembly x86 nasm dos fasm