Author Topic: Problems programming with NASM in SASM  (Read 9943 times)

Offline xedge

  • New Member
  • Posts: 1
Problems programming with NASM in SASM
« on: February 17, 2016, 06:22:40 AM »
Hi everyone,

I'm new at the forum and at assembler programming.

I'm actually using a book that can help me guide myself from the start. But I'm having problems with the compiler.

I get this error message in the console when I try to run an assembler program.

[23:55:38] Warning! Errors have occurred in the build:
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0xb): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x10): undefined reference to `read_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x1f): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x24): undefined reference to `read_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x3d): undefined reference to `sub_dump_regs'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x4b): undefined reference to `sub_dump_mem'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x55): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x5f): undefined reference to `print_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x69): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x73): undefined reference to `print_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x7d): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x84): undefined reference to `print_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x89): undefined reference to `print_nl'
c:/program files (x86)/sasm/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../libmingw32.a(main.o): In function `main':
C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16'

This is the assembler program



;
; file: first.asm
; First assembly program. This program asks for two integers as
; input and prints out their sum.
;
; To create executable:
; Using djgpp:
; nasm -f coff first.asm
; gcc -o first first.o driver.c asm_io.o
;
; Using Linux and gcc:
; nasm -f elf first.asm
; gcc -o first first.o driver.c asm_io.o
;
; Using Borland C/C++
; nasm -f obj first.asm
; bcc32 first.obj driver.c asm_io.obj
;
; Using MS C/C++
; nasm -f win32 first.asm
; cl first.obj driver.c asm_io.obj
;
; Using Open Watcom
; nasm -f obj first.asm
; wcl386 first.obj driver.c asm_io.obj

%include "asm_io.inc"
;
; initialized data is put in the .data segment
;
segment .data
;
; These labels refer to strings used for output
;
prompt1 db    "Enter a number: ", 0       ; don't forget nul terminator
prompt2 db    "Enter another number: ", 0
outmsg1 db    "You entered ", 0
outmsg2 db    " and ", 0
outmsg3 db    ", the sum of these is ", 0


;
; uninitialized data is put in the .bss segment
;
segment .bss
;
; These labels refer to double words used to store the inputs
;
input1  resd 1
input2  resd 1

 

;
; code is put in the .text segment
;
segment .text
        global  _asm_main
_asm_main:
        enter   0,0               ; setup routine
        pusha

        mov     eax, prompt1      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input1], eax     ; store into input1

        mov     eax, prompt2      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input2], eax     ; store into input2

        mov     eax, [input1]     ; eax = dword at input1
        add     eax, [input2]     ; eax += dword at input2
        mov     ebx, eax          ; ebx = eax
        dump_regs 1               ; dump out register values
        dump_mem 2, outmsg1, 1    ; dump out memory
;
; next print out result message as series of steps
;
        mov     eax, outmsg1
        call    print_string      ; print out first message
        mov     eax, [input1]     
        call    print_int         ; print out input1
        mov     eax, outmsg2
        call    print_string      ; print out second message
        mov     eax, [input2]
        call    print_int         ; print out input2
        mov     eax, outmsg3
        call    print_string      ; print out third message
        mov     eax, ebx
        call    print_int         ; print out sum (ebx)
        call    print_nl          ; print new-line

        popa
        mov     eax, 0            ; return back to C
        leave                     
        ret

I already have the asm_io.inc in the right folder but i don't know what to do next. I'll appreciate any advice of help

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Problems programming with NASM in SASM
« Reply #1 on: February 17, 2016, 08:10:45 AM »
Hi everyone,

I'm new at the forum and at assembler programming.

Hey xedge,

Welcome to the forum.  :)

I'm actually using a book that can help me guide myself from the start. But I'm having problems with the compiler.

I get this error message in the console when I try to run an assembler program.

[23:55:38] Warning! Errors have occurred in the build:
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0xb): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x10): undefined reference to `read_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x1f): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x24): undefined reference to `read_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x3d): undefined reference to `sub_dump_regs'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x4b): undefined reference to `sub_dump_mem'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x55): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x5f): undefined reference to `print_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x69): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x73): undefined reference to `print_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x7d): undefined reference to `print_string'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x84): undefined reference to `print_int'
C:\Users\Edgardo\AppData\Local\Temp\SASM\program.o:C:\Users\Edgardo\A:(.text+0x89): undefined reference to `print_nl'
c:/program files (x86)/sasm/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../libmingw32.a(main.o): In function `main':
C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16'

These "undefined reference to" messages are from your linker. Apparently it doesn't know where those procedures are located at, and when your program references them it gets confused while trying to fix-up the references.

This is the assembler program


Code: (file.asm) [Select]
;
; file: first.asm
; First assembly program. This program asks for two integers as
; input and prints out their sum.
;
; To create executable:
; Using djgpp:
; nasm -f coff first.asm
; gcc -o first first.o driver.c asm_io.o
;
; Using Linux and gcc:
; nasm -f elf first.asm
; gcc -o first first.o driver.c asm_io.o
;
; Using Borland C/C++
; nasm -f obj first.asm
; bcc32 first.obj driver.c asm_io.obj
;
; Using MS C/C++
; nasm -f win32 first.asm
; cl first.obj driver.c asm_io.obj
;
; Using Open Watcom
; nasm -f obj first.asm
; wcl386 first.obj driver.c asm_io.obj

%include "asm_io.inc"
;
; initialized data is put in the .data segment
;
segment .data
;
; These labels refer to strings used for output
;
prompt1 db    "Enter a number: ", 0       ; don't forget nul terminator
prompt2 db    "Enter another number: ", 0
outmsg1 db    "You entered ", 0
outmsg2 db    " and ", 0
outmsg3 db    ", the sum of these is ", 0


;
; uninitialized data is put in the .bss segment
;
segment .bss
;
; These labels refer to double words used to store the inputs
;
input1  resd 1
input2  resd 1

 

;
; code is put in the .text segment
;
segment .text
        global  _asm_main
_asm_main:
        enter   0,0               ; setup routine
        pusha

        mov     eax, prompt1      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input1], eax     ; store into input1

        mov     eax, prompt2      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input2], eax     ; store into input2

        mov     eax, [input1]     ; eax = dword at input1
        add     eax, [input2]     ; eax += dword at input2
        mov     ebx, eax          ; ebx = eax
        dump_regs 1               ; dump out register values
        dump_mem 2, outmsg1, 1    ; dump out memory
;
; next print out result message as series of steps
;
        mov     eax, outmsg1
        call    print_string      ; print out first message
        mov     eax, [input1]     
        call    print_int         ; print out input1
        mov     eax, outmsg2
        call    print_string      ; print out second message
        mov     eax, [input2]
        call    print_int         ; print out input2
        mov     eax, outmsg3
        call    print_string      ; print out third message
        mov     eax, ebx
        call    print_int         ; print out sum (ebx)
        call    print_nl          ; print new-line

        popa
        mov     eax, 0            ; return back to C
        leave                     
        ret

I already have the asm_io.inc in the right folder but i don't know what to do next. I'll appreciate any advice of help

You need to move the asm_io.o file to the same folder then append it to the GCC comand you are using to compile with. I'm assuming (from the comments in your source) this file has the procedures your linker is looking for.

PS: Whenever you post source code on the forum, it makes it much easier to read your code when you put it in CODE tags, like this:

[code]Your code here.[/code]

This will look like:

Code: [Select]
Your code here.
« Last Edit: February 17, 2016, 08:16:24 AM by Bryant Keller »

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Problems programming with NASM in SASM
« Reply #2 on: February 17, 2016, 09:27:44 AM »
Ah, looks like Dr. Carter's stuff. As I recall, you'll have to assemble asm_io.asm as "-f win32". That will give you "asm_io.obj" (or possibly "asm_io.o"?). That file needs to be linked with "driver.obj" and "first.obj" (or .o). So you have to assemble this file first. You may need to define something, too. You only need to do it once.

You seem to be getting these errors from SASM. I'm not familiar with SASM, but however you let SASM know about "asm_io.obj", you've got to do it. It'll need to be on the command line to gcc, ultimately. It's the linker, ld, that needs it but gcc knows what to tell the linker.

The errors from gcc may indicate something else wrong... can't find "winmain"?... that should be in the "startup code" - the stuff that calls main... not a Nasm problem...

"asm_io.inc" - which you have(?) - tells Nasm that some routines are "extern" (and it provides some macros). Nasm puts some info in the .obj file to tell the linker to look for those routines. It looks like things went along that far. Now the linker needs to be able to find them in "asm_io.obj"... and that doesn't seem to be happening.

Give it another shot with that in mind, xedge, and get back to us.  It gets easier after the first time, honest!

Best,
Frank