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
我一直在尝试将一个示例从 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