Author Topic: How to get Dr Paul Carter's linux example code to compile on 64 bit linux?  (Read 11014 times)

Offline georgelappies

  • Jr. Member
  • *
  • Posts: 12
Hi all

Could anybody please assist with getting the example code to compile on 64 bit Linux.  The commands I run from the command line is:

Code: [Select]
nasm -f elf first.asm

This runs without an issue, I then run:
Code: [Select]
gcc -o first first.o driver.c asm_io.o

This however gives the following error:

Code: [Select]
driver.c:3:1: warning: ‘cdecl’ attribute ignored [-Wattributes]
/usr/bin/ld: i386 architecture of input file `first.o' is incompatible with i386:x86-64 output
/usr/bin/ld: i386 architecture of input file `asm_io.o' is incompatible with i386:x86-64 output
collect2: ld returned 1 exit status

Here is the first.asm code (if posting this code here taken from Dr. Paul Carter's web site is in breach of any copyright please remove it).
Code: [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




And the driver.c code:
Code: [Select]
#include "cdecl.h"

int PRE_CDECL asm_main( void ) POST_CDECL;

int main()
{
  int ret_status;
  ret_status = asm_main();
  return ret_status;
}

Basically I am going through the book and want to experiment with the assembly code but I can't get it to compile on 64 bit Ubuntu Linux. Any advice will be most appreciated.

Offline Cyrill Gorcunov

  • NASM Developer
  • Full Member
  • *****
  • Posts: 179
  • Country: 00
I've not read your source code, but for 64 bit executable you need to use Elf64, ie
Code: [Select]
nasm -f elf64 some-file.asm

Offline georgelappies

  • Jr. Member
  • *
  • Posts: 12
I've not read your source code, but for 64 bit executable you need to use Elf64, ie
Code: [Select]
nasm -f elf64 some-file.asm

Thanks Cyrill, It however now opens up incompatibility in the source code with 64 bit systems. Guess I will have to setup a 32 bit VM for this.

Offline Cyrill Gorcunov

  • NASM Developer
  • Full Member
  • *****
  • Posts: 179
  • Country: 00
I suspect you need more changes in 64 bit code, see http://www.nasm.us/doc/nasmdo11.html

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
64-bit code would require massive changes! To tell gcc we want 32-bit code, it should only require adding "-m32" to gcc's command line. ("-melf_i386" for ld, if you're using it alone) Your 64-bit system should run 32-bit code with no need of a VM. That's all untested - haven't got a 64-bit system...

Best,
Frank


Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 429
  • Country: us
A 64-bit OS easily handles 32-bit apps.  The problem you're going to run into is calling conventions if trying to use assembly code written for 32-bit and recompiling for native 64-bit.  Assemble your app as nasm -elf32 ( use -m32 for gcc when linking ) and you'll be fine.

If you wish to move up to native x64 programming then reference http://www.x86-64.org/.