nasm/ld failing to do %include on cygwin

0

I'm trying to assemble using nasm on Cygwin 32 bits (following Part IV of Dandamudi, Sivarama P. Guide to Assembly Language Programming in Linux. New York: Springer, 2005).

However, I get the following errors:

$ nasm -f win32 sample.asm 
$ nasm -f win32 io.mac
$ ld -m i386pe io.obj -lc sample.obj -o sample.exe
sample.obj:sample.asm:(.text+0x7): undefined reference to `proc_PutStr'
sample.obj:sample.asm:(.text+0x19): undefined reference to `proc_GetStr'
sample.obj:sample.asm:(.text+0x26): undefined reference to `proc_PutStr'
sample.obj:sample.asm:(.text+0x2e): undefined reference to `proc_GetInt'
sample.obj:sample.asm:(.text+0x3e): undefined reference to `proc_PutStr'
sample.obj:sample.asm:(.text+0x49): undefined reference to `proc_PutInt'
sample.obj:sample.asm:(.text+0x56): undefined reference to `proc_PutStr'
sample.obj:sample.asm:(.text+0x63): undefined reference to `proc_GetCh'
sample.obj:sample.asm:(.text+0x80): undefined reference to `proc_PutStr'
sample.obj:sample.asm:(.text+0x8c): undefined reference to `proc_PutStr'
sample.obj:sample.asm:(.text+0x92): undefined reference to `proc_nwln'
$ 

Now, io.mac has reference to external procedures (e.g., proc_GetStr and proc_GetCh, which I assume come from an external library) but I couldn't find how to reference these externals.

Anyone can suggest what should I do?


Below are the various code/elaborations:

$ cat sample.asm
;An example assembly language program               SAMPLE.ASM
;
;         Objective: To demonstrate the use of some I/O
;                    routines and to show the structure
;                    of assembly language programs.
;            Inputs: As prompted.
;           Outputs: As per input.
%include  "io.mac"

.DATA
name_msg      db   'Please enter your name: ',0
query_msg     db   'How many times to repeat welcome message? ',0
confirm_msg1  db   'Repeat welcome message ',0
confirm_msg2  db   ' times? (y/n) ',0 
welcome_msg   db   'Welcome to Assembly Language Programming ',0

.UDATA
user_name    resb  16             ; buffer for user name
response     resb  1

.CODE
     .STARTUP
     PutStr  name_msg            ; prompt user for his/her name
     GetStr  user_name,16        ; read name (max. 15 characters)
ask_count:
     PutStr  query_msg           ; prompt for repeat count
     GetInt  CX                  ; read repeat count
     PutStr  confirm_msg1        ; confirm repeat count
     PutInt  CX                  ; by displaying its value
     PutStr  confirm_msg2
     GetCh   [response]          ; read user response
     cmp     byte [response],'y' ; if 'y', display welcome message
     jne     ask_count           ; otherwise, request repeat count
display_msg:
     PutStr  welcome_msg         ; display welcome message
     PutStr  user_name           ; display the user name
     nwln
     loop    display_msg         ; repeat count times
     .EXIT   



$ cat io.mac
extern   proc_nwln, proc_PutCh, proc_PutStr
extern   proc_GetStr, proc_GetCh
extern   proc_PutInt, proc_GetInt
extern   proc_PutLInt, proc_GetLInt

;;-------------------------------------------------------------------
%macro  .STARTUP  0
;group dgroup .data .bss
        global   _start
_start:
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  .EXIT  0
        mov    EAX,1
        xor    EBX,EBX
        int    0x80
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  .DATA 0
        segment .data
%endmacro
;;-------------------------------------------------------------------

;;-------------------------------------------------------------------
%macro  .UDATA 0
        segment .bss
%endmacro
;;-------------------------------------------------------------------

;;-------------------------------------------------------------------
%macro  .CODE 0
        segment .data
        segment .bss
        segment .text
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  nwln  0 
        call    proc_nwln
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  PutCh  1 
        push    AX
        mov     AL,%1
        call    proc_PutCh
        pop     AX
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  PutStr  1 
        push    ECX
        mov     ECX,%1
        call    proc_PutStr
        pop     ECX
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  GetStr  1-2 81
        push    ESI
        push    EDI
        mov     EDI,%1
        mov     ESI,%2
        call    proc_GetStr
        pop     EDI
        pop     ESI
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  GetCh   1
        push    SI
        xor     SI,SI
%ifidni %1,AL
        ;inc     SI
        call    proc_GetCh
%elifidni %1,AH
        mov     SI,1
        call    proc_GetCh
%else
        push    AX
        call    proc_GetCh
        mov     %1,AL
        pop     AX
%endif
        pop     SI
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  PutInt  1
        push    AX
        mov     AX,%1
        call    proc_PutInt
        pop     AX
%endmacro
;;-------------------------------------------------------------------


;;-------------------------------------------------------------------
%macro  GetInt  1
%ifnidni %1,AX
        push    AX
        call    proc_GetInt
        mov     %1,AX
          pop     AX
%else 
        call  proc_GetInt
%endif
%endmacro
;;-------------------------------------------------------------------

;;-------------------------------------------------------------------
%macro  PutLInt  1
        push    EAX
        mov     EAX,%1
        call    proc_PutLInt
        pop     EAX
%endmacro
;;-------------------------------------------------------------------

;;-------------------------------------------------------------------
%macro  GetLInt  1
%ifnidni %1,EAX
        push    EAX
        call    proc_GetLInt
        mov     %1,EAX
          pop     EAX
%else 
        call  proc_GetLInt
%endif
%endmacro
;;-------------------------------------------------------------------

$ objdump -t io.obj

io.obj:     file format pe-i386

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 io.mac
File 
[  2](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 .absolut
[  3](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_nwln
[  4](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutCh
[  5](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutStr
[  6](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetStr
[  7](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetCh
[  8](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutInt
[  9](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetInt
[ 10](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutLInt
[ 11](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetLInt
[ 12](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000001 @feat.00

$ objdump -t sample.obj 

sample.obj:     file format pe-i386

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 sample.asm
File 
[  2](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x95 nreloc 0 nlnno 0
[  4](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x11 nreloc 0 nlnno 0
[  6](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0xa1 nreloc 20 nlnno 0
[  8](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 .absolut
[  9](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_nwln
[ 10](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutCh
[ 11](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutStr
[ 12](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetStr
[ 13](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetCh
[ 14](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutInt
[ 15](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetInt
[ 16](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_PutLInt
[ 17](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 proc_GetLInt
[ 18](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 name_msg
[ 19](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000019 query_msg
[ 20](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000044 confirm_msg1
[ 21](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000005c confirm_msg2
[ 22](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000006b welcome_msg
[ 23](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 user_name
[ 24](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000010 response
[ 25](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _start
[ 26](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000001f ask_count
[ 27](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000079 display_msg
[ 28](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000001 @feat.00

$ 
assembly
macros
include
cygwin
nasm
asked on Stack Overflow Dec 6, 2014 by boardrider • edited Dec 6, 2014 by boardrider

2 Answers

1

Your error was to assemble io.mac. It is a textfile which is included in sample.asm "as is". io.obj is not an assembled io.mac. With assembling io.mac you destroyed the original io.obj. But even if you extract the original io.obj from win_nasm_progs.zip you will fail. It is not a Windows file but a MS-DOS file (yes, this is very annoying). You can't either use the Linux file (io.o) because Cygwin needs Windows system calls. So you can't use the samples of Dandamudi's book outside of Linux. The only thing that comes to my mind is changing the calls in io.mac to calls to a C-function (and other adjusts) and linking the object file against GCC.

answered on Stack Overflow Dec 6, 2014 by rkhb
0

I decided to abandon the I/O scheme from Guide to Assembly Language Programming in Linux and go with that (which works on Cygwin/nasm) of Carter, Paul A. PC assembly language. Raleigh, NC: Lulu Press, 2007(i.e., its driver.c cdecl.h asm_io.inc asm_io.asm files)

answered on Stack Overflow Dec 7, 2014 by boardrider

User contributions licensed under CC BY-SA 3.0