My exact issue is that am trying to get the linked final exe from 3 files namely:
c
loaderasm
fileI manage to convert them all successfully to their subsequent object files, but when linking, I get the undefined reference to 'asm_main()' error.
My C
file is simple and looks like this:
#include "cdecl.h"
int PRE_CDECL asm_main( void ) POST_CDECL;
int main()
{
int ret_status;
ret_status = asm_main();
return ret_status ;
}
It points to the main asm
file that has the following section:
%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
The asm_io file is located here: https://github.com/nateware/cpp/blob/master/assembly/asm_io.asm
With the use of djgpp mingw(prebuillt 12.2.0)
to compile and NASM(2.16.01)
as well for asm.
The commands I've used include:
i586-pc-msdosdjgpp-gcc.exe -c driver.c
nasm -f coff first.asm
nasm -f coff asm_io.asm
For the final linking i used:
i586-pc-msdosdjgpp-gcc.exe -o first driver.o first.o asm_io.o
Additional things i have done:
Instead of using nasm -f coff first.asm i used nasm -f win32 first.asm
Instead of nasm -f coff asm_io.asm i used nasm -f win32 -d COFF_TYPE asm_io.asm
Finally i did gcc driver.o first.obj asm_io.obj -o first.exe
The following errors now arise:
6 architecture of input file `asm_io.obj' is incompatible with i386:x86-64 output
driver.o:driver.c:(.text+0xe): undefined reference to `asm_main'
asm_io.obj:asm_io.asm:(.text+0x10): undefined reference to `_scanf'
asm_io.obj:asm_io.asm:(.text+0x2a): undefined reference to `_printf'
asm_io.obj:asm_io.asm:(.text+0x41): undefined reference to `_printf'
asm_io.obj:asm_io.asm:(.text+0x52): undefined reference to `_getchar'
asm_io.obj:asm_io.asm:(.text+0x68): undefined reference to `_putchar'
asm_io.obj:asm_io.asm:(.text+0x7a): undefined reference to `_putchar'
asm_io.obj:asm_io.asm:(.text+0x149): undefined reference to `_printf'
asm_io.obj:asm_io.asm:(.text+0x16c): undefined reference to `_printf'
asm_io.obj:asm_io.asm:(.text+0x198): undefined reference to `_printf'
asm_io.obj:asm_io.asm:(.text+0x1bf): undefined reference to `_printf'
asm_io.obj:asm_io.asm:(.text+0x1d8): undefined reference to `_printf'
No matter what I have done to try and get the final exe, I've failed. Any help or something i am missing?
For Further Context: This is from the book PCASM by Paul Carter: https://github.com/nateware/cpp/blob/master/assembly/first.asm Included CDEHL header file: header file The assembly input\output file is located here:I/O
The easiest way to make examples of that book work on your system is using the 32-bit MinGW GCC. As soon as you have it set up, these commands work:
gcc -c driver.c
nasm -f win32 -o first.o first.asm
nasm -f win32 -o asm_io.o asm_io.asm
gcc -o first driver.o first.o asm_io.o
first.exe
If you get an error, please copy-paste all the commands you have run (including gcc -v
), and the full output of each to your question, and then add a comment stating that you have extended the question.
Before installing anything to your system (64-bit Windows), remove all of these: DJGPP, MinGW (32-bit and 64-bit), MinGW-w64, MSYS, MSYS2. You can keep NASM.
You can get the 32-bit MinGW GCC by following any (one) of these methods:
Directly from MINGW32. (I think this one is easier.)
Installing MSYS2, setting the environment variable MSYS=MINGW32
(to select the MINGW32 environment), starting the MSYS2 shell window, installing GCC.
Unfortunately I'm not able to help you with the installation beyond what I aready wrote. If you get stuck, ask a separate question on StackOverflow.
If you are unsure whether your GCC is 32-bit or 64-bit, run gcc -v
, and look at the line starting with Target:
. If it contains 64, then it's 64-bit. If it contains i386, i486, i586 or i686, then it's 32-bit. You need 32-bit. If you get 64-bit, then you've installed the wrong GCC, you have to uninstall it, and install the right one. If needed, ask a separate question on StackOverflow.
Don't use DJGPP, because it creates DOS .exe files, and those don't work on 64-bit Windows systems such as your system. (You may get an error about missing 16-bit support. It doesn't matter that your .asm files have 32-bit code, DOS .exe files won't work on your system, and DJGPP is not able to create anything else.)
For this project, don't use 64-bit GCC (e.g. in MinGW-w64), because it generates 64-bit Windows .exe files, which require 64-bit .asm files, and your book contains only 32-bit .asm files.