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
$
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.
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)
User contributions licensed under CC BY-SA 3.0