Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.os.msdos.programmer > #4192

Re: Looking for .COM program sources in NASM Assembly

From Herbert Kleebauer <klee@unibwm.de>
Newsgroups comp.os.msdos.programmer
Subject Re: Looking for .COM program sources in NASM Assembly
Date 2022-09-06 00:03 +0200
Organization Aioe.org NNTP Server
Message-ID <tf5rnk$p4p$1@gioia.aioe.org> (permalink)
References <24f4d454-83f3-4c20-878b-f7a303cdffffn@googlegroups.com>

Show all headers | View raw


On 04.09.2022 12:48, Paolo Amoroso wrote:

 > I'm looking for source code of MS-DOS .COM programs in real-mode 8086
 > Assembly written in NASM syntax. Any repositories or recommendations?

 > I'm learning Assembly programming under MS-DOS (and MikeOS). To avoid
 > the complexity of x86 segmentation, for the time being I prefer to focus
 > on single-segment programs, as I plan to write small programs anyway.
 > So I'd like to study examples of how such systems organize and reference
 > data and code. I searched a bit but found remarkably little .COM code.

But it doesn't make much sense to write .com programs which can't
be run natively on a current computer system. Windows programs also
don't use segmentation and there in no difference in the assembly code
for DOS and Windows (as long as you use also 32 bit instructions in DOS,
which makes things much easier). The big difference is, that there
is no such simple file format as the .com format in DOS so you will have
to use a linker which generates the proper file structure for a Windows
binary.

But if you really want, you can also generate any byte if the .exe
file by your assembler source code so NASM directly generates the
exe file. Here an example for a simple program which reads from
stdin, converts any lowercase letter to upper case and writes it
to stdout (the code itself starts at the label winmain, the rest
is just the data of the exe file format). Because NASM uses an awful
syntax you have to include "mac.inc" to be able to use a readable
instruction format (I post mac.inc in a follow up):


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; upper.asm: copy stdin to stdout, convert a-z to A-Z            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

         ; nasm -O99 -f bin -o upper.exe upper.asm
         %include "mac.inc"

UseIdatSection equ 0 ; 0 if no idat section is used
UseUdatSection equ 0 ; 0 if no udat section is used

;#==================================================================#
;#                    Start of Headers                              #
;#==================================================================#

;       +--------------------------------------------+
;       |         Start of DOS Header                |
;       +--------------------------------------------+

         section .text vstart=0

doshead_start:
                                 ; DOS .EXE header
         dc.b    'MZ'            ; Magic number
         dc.w    dosfilesize % 512 ; Bytes on last page of file (0->512)
         dc.w    (dosfilesize-1)/512+1
                                 ; Pages in file (Page=512 byte)
         dc.w    0               ; Relocations (nr of entries)
         dc.w    doshead_size/16 ; Size of header size in paragraphs (16 byte)
         dc.w    0               ; Minimum extra paragraphs needed
         dc.w    $0ffff          ; Maximum extra paragraphs needed
         dc.w    0               ; Initial (relative) SS value (ss=load_adr+nr)
         dc.w    dosstack        ; Initial SP value
         dc.w    0               ; Checksum
         dc.w    dosmain         ; Initial IP value
         dc.w    0               ; Initial (relative) CS value (cs=load_adr+nr)
         dc.w    reloc           ; File address of relocation table
         dc.w    0               ; Overlay number
         dc.w    0,0,0,0         ; Reserved words
         dc.w    0               ; OEM identifier (for e_oeminfo)
         dc.w    0               ; OEM information; e_oemid specific
         dc.l    0,0,0,0,0       ; Reserved words
         dc.l    WinHeader       ; File address of new exe header
reloc:
doshead_end:
doshead_size equ doshead_end-doshead_start

         @@0 equ $-$$                  ; current file position

         section .text0 vstart=0

dosstart:
dosmain:move.w   s6,-[sp]
         move.w   [sp]+,s0
         move.w   .text,r1
         move.b   $09,m0
         trap     $21
         move.w   $4c01,r0
         trap     $21
text:  dc.b    'Nice to meet somebody who is still using DOS,',13,10
         dc.b    'but this program requires Win32.',13,10,'$'
         align 16, db 0

dosstack equ $+256          ; 256 Byte stack
dosfilesize equ $-dosstart+256

;       +--------------------------------------------+
;       |           End of DOS Header                |
;       +--------------------------------------------+


;       +--------------------------------------------+
;       |         Start of Windows Header            |
;       +--------------------------------------------+

         ImageBase equ   $00400000
         SectionAlignment equ 4096
         FileAlignment equ     512

         @@1 equ @@0 + $-$$            ; current file position
         WinHeader equ @@1

         section .text1 vstart=ImageBase
         ImageBase1 equ $
;       ImageBase1 has same value as ImageBase but is nonrelatve

                                       ; see WINNT.H for information
         dc.b   'PE',0,0               ; magic word
                                       ; _IMAGE_FILE_HEADER:
         dc.w    $014c                 ; Machine ($014c=Intel x86 processor)
         dc.w    NumberOfSections      ; NumberOfSections
         dc.l    $36a57950             ; TimeDateStamp (seconds since  31.12.69 16:00)
         dc.l    0                     ; PointerToSymbolTable
         dc.l    0                     ; NumberOfSymbols
         dc.w    SizeOfOptionalHeader  ; SizeOfOptionalHeader
         dc.w    $010f                 ; Charcteristics

         ; 0x0001 Relocation info stripped from file.
         ; 0x0002 File is executable  (i.e. no unresolved externel references).
         ; 0x0004 Line nunbers stripped from file.
         ; 0x0008 Local symbols stripped from file.
         ; 0x0010 Agressively trim working set
         ; 0x0080 Bytes of machine word are reversed.
         ; 0x0100 32 bit word machine.
         ; 0x0200 Debugging info stripped from file in .DBG file
         ; 0x0400 If Image is on removable media, copy and run from the swap file.
         ; 0x0800 If Image is on Net, copy and run from the swap file.
         ; 0x1000 System File.
         ; 0x2000 File is a DLL.
         ; 0x4000 File should only be run on a UP machine
         ; 0x8000 Bytes of machine word are reversed.

         @a1 equ $                     ; _IMAGE_OPTIONAL_HEADER
         dc.w    $010b                 ; Magic
         dc.b    5                     ; MajorLinkerVersion
         dc.b    12                    ; MinorLinkerVersion
         dc.l    SizeOfCode            ; SizeOfCode
         dc.l    SizeOfInitializedData ; SizeOfInitializedData
         dc.l    SizeOfUninitializedData ; SizeOfUninitializedData
         dc.l    winmain-ImageBase     ; AddressOfEntryPoint
         dc.l    BaseOfCode            ; BaseOfCode
         dc.l    BaseOfData            ; BaseOfData
         dc.l    ImageBase             ; ImageBase
         dc.l    SectionAlignment      ; SectionAlignment
         dc.l    FileAlignment         ; FileAlignment
         dc.w    4                     ; MajorOperatingSystemVersion
         dc.w    0                     ; MinorOperatingSystemVersion
         dc.w    0                     ; MajorImageVersion
         dc.w    0                     ; MinorImageVersion
         dc.w    4                     ; MajorSubsystemVersion
         dc.w    0                     ; MinorSubsystemVersion
         dc.l    0                     ; Win32VersionValue
         dc.l    SizeOfImage           ; SizeOfImage
         dc.l    SizeOfHeaders         ; SizeOfHeaders
         dc.l    0                     ; CheckSum
         dc.w    3                     ; Subsystem
                 ; 0:  Unknown subsystem.
                 ; 1:  Image doesn't require a subsystem.
                 ; 2:  Image runs in the Windows GUI subsystem.
                 ; 3:  Image runs in the Windows character subsystem.
                 ; 5:  image runs in the OS/2 character subsystem.
                 ; 7:  image run  in the Posix character subsystem.
                 ; 8:  image run  in the 8 subsystem.
         dc.w    $0000                 ; DllCharacteristics
         dc.l    $00100000             ; SizeOfStackReserve
         dc.l    $00001000             ; SizeOfStackCommit
         dc.l    $00100000             ; SizeOfHeapReserve
         dc.l    $00001000             ; SizeOfHeapCommit
         dc.l    $00000000             ; LoaderFlags
         dc.l    NumberOfRvaAndSize    ; NumberOfRvaAndSize (entries
                                       ; in the data dir)

;       ..............................................
;       :      Start of Image Data Directory         :
;       ..............................................

                 ; virtual address, size
         @b equ $
         dc.l    0,0                     ; Export Directory
         dc.l    imp_start,imp_size      ; Import Directory
         dc.l    0,0                     ; Resource Directory
         dc.l    0,0                     ; Exception Directory
         dc.l    0,0                     ; Security Directory
         dc.l    0,0                     ; Base Relocation Table
         dc.l    0,0                     ; Debug Directory
         dc.l    0,0                     ; Description String
         dc.l    0,0                     ; Machine Value (MIPS GP)
         dc.l    0,0                     ; TLS Directory
         dc.l    0,0                     ; Load Configuration Directory
         dc.l    0,0                     ; Bound Import Directory in headers
         dc.l    iat_start,iat_size      ; Import Address Table
         dc.l    0,0                     ; 14
         dc.l    0,0                     ; 15
         dc.l    0,0                     ; 16

         NumberOfRvaAndSize   equ ($-@b)/8
         SizeOfOptionalHeader equ $-@a1

;       ..............................................
;       :        End of Image Data Directory         :
;       ..............................................

;       ..............................................
;       :      Start of Image Sections Header        :
;       ..............................................

         @a2 equ $

         dc.b    '.text',0,0,0   ; name
         dc.l    VSizeOf_text    ; virtual size
         dc.l    VBaseOf_text    ; virtual address
         dc.l    FSizeOf_text    ; size of raw data
         dc.l    FBaseOf_text    ; pointer to raw data
         dc.l    0               ; pointer to relocatins
         dc.l    0               ; pointer to line numbers
         dc.w    0               ; number of relocations
         dc.w    0               ; number of line numbers
         dc.l    $0e0000020      ; characteristics


         %IF UseIdatSection <> 0
         dc.b    '.idat',0,0,0   ; name
         dc.l    VSizeOf_idat    ; virtual size
         dc.l    VBaseOf_idat    ; virtual address
         dc.l    FSizeOf_idat    ; size of raw data
         dc.l    FBaseOf_idat    ; pointer to raw data
         dc.l    0               ; pointer to relocatins
         dc.l    0               ; pointer to line numbers
         dc.w    0               ; number of relocations
         dc.w    0               ; number of line numbers
         dc.l    $0e0000040      ; characteristics
         %ENDIF

         %IF UseUdatSection <> 0
         dc.b    '.udat',0,0,0   ; name
         dc.l    VSizeOf_udat    ; virtual size
         dc.l    VBaseOf_udat    ; virtual address
         dc.l    FSizeOf_udat    ; size of raw data
         dc.l    FBaseOf_udat    ; pointer to raw data
         dc.l    0               ; pointer to relocatins
         dc.l    0               ; pointer to line numbers
         dc.w    0               ; number of relocations
         dc.w    0               ; number of line numbers
         dc.l    $0e0000080      ; characteristics
         %ENDIF

         NumberOfSections equ ($-@a2)/40

;      ..............................................
;      :        End of Image Sections Header        :
;      ..............................................

        ; characteristics
        ; 0x00000020  // Section contains code.
        ; 0x00000040  // Section contains initialized data.
        ; 0x00000080  // Section contains uninitialized data.
        ; 0x00000200  // Section contains comments or some other type of information.
        ; 0x00000800  // Section contents will not become part of image.
        ; 0x00001000  // Section contents comdat.
        ; 0x01000000  // Section contains extended relocations.
        ; 0x02000000  // Section can be discarded.
        ; 0x04000000  // Section is not cachable.
        ; 0x08000000  // Section is not pageable.
        ; 0x10000000  // Section is shareable.
        ; 0x20000000  // Section is executable.
        ; 0x40000000  // Section is readable.
        ; 0x80000000  // Section is writeable.

;      +--------------------------------------------+
;      |           End of Windows Header            |
;      +--------------------------------------------+


         @@2 equ @@1 + ($-$$)                  ; current file position
         times ((@@2+FileAlignment-1)/FileAlignment*FileAlignment)-@@2  db 0
         @@3 equ @@1 + ($-$$)                  ; current file position

         SizeOfHeaders equ @@3

;#==================================================================#
;#                      End of Headers                              #
;#==================================================================#

;#==================================================================#
;#                     Start of Sections                            #
;#==================================================================#

;      +--------------------------------------------+
;      |         Start of .text Section             |
;      +--------------------------------------------+

FBaseOf_text equ @@3
VBaseOf_text equ ($-ImageBase1+SectionAlignment-1)/SectionAlignment*SectionAlignment

BaseOfCode equ VBaseOf_text
section .text2 vstart=ImageBase+VBaseOf_text
ImageBase2 equ $-VBaseOf_text
; ImageBase2 has same value as ImageBase but is nonrelatve



;      ..............................................
;      :         Start of Thunk Table               :
;      ..............................................


        iat_start equ $-ImageBase

KERNEL32_thunk:
ExitProcess:    dc.l        KERNEL32_ExitProcess        -ImageBase
GetStdHandle:   dc.l        KERNEL32_GetStdHandle       -ImageBase
ReadFile:       dc.l        KERNEL32_ReadFile           -ImageBase
WriteFile:      dc.l        KERNEL32_WriteFile          -ImageBase
                 dc.l        0


        iat_size equ $-ImageBase-iat_start

;      ..............................................
;      :           End of Thunk Table               :
;      ..............................................


;      ..............................................
;      :         Start of Import Directory          :
;      ..............................................


             imp_start equ $-ImageBase

             imp:

             dc.l    KERNEL32_import     -ImageBase
             dc.l    0
             dc.l    0
             dc.l    KERNEL32_name       -ImageBase
             dc.l    KERNEL32_thunk      -ImageBase

             dc.l    0
             dc.l    0
             dc.l    0
             dc.l    0
             dc.l    0

             imp_size equ $-imp

;      ..............................................
;      :           End of Import Directory          :
;      ..............................................



KERNEL32_name:
             dc.b    'KERNEL32.dll',0
             align 2 , db 0

KERNEL32_import:
             dc.l    KERNEL32_ExitProcess        -ImageBase
             dc.l    KERNEL32_GetStdHandle       -ImageBase
             dc.l    KERNEL32_ReadFile           -ImageBase
             dc.l    KERNEL32_WriteFile          -ImageBase
             dc.l    0
             align 2, db 0

KERNEL32_ExitProcess:
             dc.w    0
             dc.b    'ExitProcess',0
             align 2, db 0
KERNEL32_GetStdHandle:
             dc.w    0
             dc.b    'GetStdHandle',0
             align 2, db 0
KERNEL32_ReadFile:
             dc.w    0
             dc.b    'ReadFile',0
             align 2, db 0
KERNEL32_WriteFile:
             dc.w    0
             dc.b    'WriteFile',0
             align 2, db 0





;      ..............................................
;      :         Start of Code                      :
;      ..............................................


         seg 32


winmain:

20:    bsr.l   getc
         cmpq.l  -1,r0
         beq.b   exit
         cmp.b   'a',r0
         blo.b   .10
         cmp.b   'z',r0
         bhi.b   .10
         add.b   'A'-'a',r0
10:    bsr.l   putc
         br.b    .20

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;          OS specific functions: getc, putc, exit                ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

exit:   move.l  r0,-[sp]
         jsr.l   [ExitProcess]   ; exit program

putc:   movem.l r0-r7,-[sp]
         eor.l   r0,r0
         add.l   [.handle],r0
         bne.b   .10
         moveq.l  -11,-[sp]
         jsr.l   [GetStdHandle]
         move.l  r0,[.handle]
10:    moveq.l 0,-[sp]
         lea.l   [r7+4*4],r1
         move.l  r1,-[sp]
         moveq.l 1,-[sp]
         addq.l  4*4,r1
         move.l  r1,-[sp]
         move.l  r0,-[sp]
         jsr.l   [WriteFile]
         or.l    r0,r0
         bne.b   .20
30:    moveq.l 0,-[sp]
         jsr.l   [ExitProcess]
20:    cmpq.l  1,[r7+3*4]
         bne.b   .30
         movem.l [sp]+,r0-r7
         rts.l

         align 4, db 0
handle:dc.l    0


getc:   eor.l   r0,r0
         movem.l r0-r7,-[sp]
         add.l   [.handle],r0
         bne.b   .10
         moveq.l -10,-[sp]
         jsr.l   [GetStdHandle]
         move.l  r0,[.handle]
10:    moveq.l 0,-[sp]
         lea.l   [r7+4*4],r1
         move.l  r1,-[sp]
         moveq.l 1,-[sp]
         addq.l  4*4,r1
         move.l  r1,-[sp]
         move.l  r0,-[sp]
         jsr.l   [ReadFile]
         or.l    r0,r0
         bne.b   .20
         moveq.l 0,-[sp]
         jsr.l   [ExitProcess]
20:    cmpq.l  1,[r7+3*4]
         beq.b   .30
         move.l  -1,[r7+7*4]
30:    movem.l [sp]+,r0-r7
         rts.l

         align 4, db 0
handle:dc.l    0



;      ..............................................
;      :           End of Code                      :
;      ..............................................

VSizeOf_text equ $-ImageBase-VBaseOf_text

         @a3 equ $-ImageBase2

         @@4 equ @@3 + ($-$$)                  ; current file position
         times ((@@4+FileAlignment-1)/FileAlignment*FileAlignment)-@@4  db 0
         @@5 equ @@3 + ($-$$)                  ; current file position

FSizeOf_text equ @@5-FBaseOf_text
SizeOfCode equ FSizeOf_text


;      +--------------------------------------------+
;      |           End of .text Section             |
;      +--------------------------------------------+


;      +--------------------------------------------+
;      |          Start of .idat Section            |
;      +--------------------------------------------+


FBaseOf_idat equ @@5
VBaseOf_idat equ (@a3+SectionAlignment-1)/SectionAlignment*SectionAlignment
BaseOfData equ VBaseOf_idat
section .text3 vstart=ImageBase+VBaseOf_idat
ImageBase3 equ $-VBaseOf_idat
; ImageBase3 has same value as ImageBase but is nonrelatve

; Insert initialized variables here (and set UseIdatSection=1
; at the top of this file). Because the code section is set
; r/w-able, you can put initialized variables also into the
; code section.

; var1:    dc.l    0
; var2:    dc.l    $12345678

VSizeOf_idat equ $-ImageBase-VBaseOf_idat
         @a4 equ $ - ImageBase3

         @@6 equ @@5 + ($-$$)                  ; current file position
         times ((@@6+FileAlignment-1)/FileAlignment*FileAlignment)-@@6  db 0
         @@7 equ @@5 + ($-$$)                  ; current file position


FSizeOf_idat equ @@7-FBaseOf_idat

;      +--------------------------------------------+
;      |            End of .idat Section            |
;      +--------------------------------------------+

SizeOfInitializedData equ FSizeOf_idat


;      +--------------------------------------------+
;      |          Start of .udat Section            |
;      +--------------------------------------------+


FBaseOf_udat equ @@7
VBaseOf_udat equ (@a4+SectionAlignment-1)/SectionAlignment*SectionAlignment
section .bss vstart=ImageBase+VBaseOf_udat
ImageBase4 equ $-VBaseOf_udat
; ImageBase4 has same value as ImageBase but is nonrelatve

; Insert uninitialized variables here (and set UseUdatSection=1
; at the top of this file). Because the code section is set
; r/w-able, you can put uninitialized variables also at the END
; of the code section (but NASM doesn't support this).

; buf1:    blk.l    10
; buf2:    blk.l   200



VSizeOf_udat equ $-ImageBase-VBaseOf_udat
FSizeOf_udat equ 0


;      +--------------------------------------------+
;      |            End of .udat Section            |
;      +--------------------------------------------+

SizeOfUninitializedData equ VSizeOf_udat
SizeOfImage equ ($-ImageBase4+SectionAlignment-1)/SectionAlignment*SectionAlignment


;#==================================================================#
;#                       End of Sections                            #
;#==================================================================#




Back to comp.os.msdos.programmer | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Looking for .COM program sources in NASM Assembly Paolo Amoroso <paolo.amoroso@gmail.com> - 2022-09-04 03:48 -0700
  Re: Looking for .COM program sources in NASM Assembly "Kerr-Mudd, John" <admin@127.0.0.1> - 2022-09-04 14:05 +0100
  Re: Looking for .COM program sources in NASM Assembly Steve Nickolas <usotsuki@buric.co> - 2022-09-04 12:47 -0400
    Re: Looking for .COM program sources in NASM Assembly Paolo Amoroso <paolo.amoroso@gmail.com> - 2022-09-05 00:39 -0700
    Re: Looking for .COM program sources in NASM Assembly "Kerr-Mudd, John" <admin@127.0.0.1> - 2022-09-05 10:54 +0100
      Re: Looking for .COM program sources in NASM Assembly Steve Nickolas <usotsuki@buric.co> - 2022-09-05 15:46 -0400
  Re: Looking for .COM program sources in NASM Assembly Herbert Kleebauer <klee@unibwm.de> - 2022-09-06 00:03 +0200
    Re: Looking for .COM program sources in NASM Assembly Herbert Kleebauer <klee@unibwm.de> - 2022-09-06 00:05 +0200
      Re: Looking for .COM program sources in NASM Assembly "Kerr-Mudd, John" <admin@127.0.0.1> - 2022-09-06 10:09 +0100
        Re: Looking for .COM program sources in NASM Assembly Herbert Kleebauer <klee@unibwm.de> - 2022-09-07 10:11 +0200
    Re: Looking for .COM program sources in NASM Assembly Paolo Amoroso <paolo.amoroso@gmail.com> - 2022-09-06 00:00 -0700
      Re: Looking for .COM program sources in NASM Assembly Herbert Kleebauer <klee@unibwm.de> - 2022-09-07 10:32 +0200

csiph-web