Home > Back-end >  Segments in NASM?
Segments in NASM?

Time:10-31

I had been trying to replicate an example from FASM (flat assembler) to NASM but I had not been able to do it and I try to understand the way NASM handles segments (sections).

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 generates a MSDOS exe file and loading this in DEBUG I see the following:

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

As you may see, FASM creates the segment and set the CALL as a far call. extra is effectively placed in a separate segment. The data segment is in a separate segment as well.

I tried doing this example in 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

And linking with wlink using this link file:

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

The generated code is different:

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

As you may see, write_text is in the same segment as the rest of the code (and apparently the data segment as well) but it was not put in a separate segment as I thought.

Am I missing something here? Is there any way to actually place code in a separate segment? Any help, guidance or explanation of what is happening or how to achieve such would be appreciated!

and yes, I tried in MASM and the same thing happens, is FASM the only one with that super power?

Thanks!

CodePudding user response:

What you want is a support for memory models, which NASM lacks, it treats intersegment transfers as NEAR and the programmer is responsible for coding CALL FAR instructions where necessary.

No, FASM is not the only assembler aware of memory models. Here is your program tailored for €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
  • Related