Error When Trying to Run .Asm File on Nasm on Ubuntu

Error when trying to run .asm file on NASM on Ubuntu

This looks like it may be a simple mismatch between what's produced by nasm and what ld is trying to make:

i386 architecture of input file 'hello.o' is incompatible with i386:x86-64 output

In other words, nasm has produced a 32-bit object file hello.o and ld wants to take that and make a 64-bit executable file.

The nasm -hf command should give you the available output formats:

valid output formats for -f are (`*' denotes default):
* bin flat-form binary files (e.g. DOS .COM, .SYS)
ith Intel hex
srec Motorola S-records
aout Linux a.out object files
aoutb NetBSD/FreeBSD a.out object files
coff COFF (i386) object files (e.g. DJGPP for DOS)
elf32 ELF32 (i386) object files (e.g. Linux)
elf ELF (short name for ELF32)
elf64 ELF64 (x86_64) object files (e.g. Linux)
as86 Linux as86 (bin86 version 0.3) object files
obj MS-DOS 16-bit/32-bit OMF object files
win32 Microsoft Win32 (i386) object files
win64 Microsoft Win64 (x86-64) object files
rdf Relocatable Dynamic Object File Format v2.0
ieee IEEE-695 (LADsoft variant) object file format
macho32 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
macho MACHO (short name for MACHO32)
macho64 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
dbg Trace of all info passed to output stage

I see that your linked tutorial asks you to run:

nasm -f elf hello.asm

Try using:

nasm -f elf64 hello.asm

instead, and you may find ld stops complaining about the input file.

how to run this assembly code on nasm?

There is no dependency to get from nibbles.S to nibbles.o. Also, helpers.o and workaround.o don't have associated source file relations. Add those relationship and it should work.

.' is not recognized when attempting to run assembly code?

'.' is not recognized as an internal or external command

Background information

The reason is that Windows works differently from Linux or Unix (and obvously your tutorials describe how to work with Linux):

If a file name ends with .exe, Windows recognizes the file as application program. If a file name ends with .bat, Windows recognizes the file as "batch" file.

Under Linux or Unix this is completely different: An application or "batch" (*) file can have any file name; a file is "marked" with a special flag telling the operating system that the file can be executed. If this flag is set, the operating system uses the file content (not the suffix of the file name) to distinguish the type of executable file (e.g. application, "batch" file, Python program ...).

The command line ld test.o -o test will generate a file that is named test, not test.exe. Under Linux this would be a valid file name for an application, under Windows the file name must end with .exe, so this is not a valid file name.

You are free to name a "batch" file test.exe and an application test.bat under Linux if you like to do so.

Under Linux the command ./test would start an application named test in the current directory; ./test.exe would start an application or "batch" file named test.exe.

Under Windows, the command for executing the file named test.exe would simply be test, not ./test.exe.

About your problem

First of all, you'll have to rename your output file: ld test.o -o test.exe

The next problem is that your program will definitely not work on Windows:

At least Windows 7 (I'm not sure about Windows 10) will refuse starting an application not using any DLL files; and the command line ld test.o -o test.exe generates an application that does not use any DLL files.

I'm quite sure your assembly program contains the int instruction or the syscall instruction.

Directly calling these instructions is operating system specific:

A program that calls int 0x80 (or int 80h or int $0x80 depending on the assembler used) will run on Linux only!


(*) This file type is named "shell script", not "batch file" in Linux; however, this is mainly a difference in terminology.

Unable to compile .asm file

Sure it is not assembler issue, but also sure it helps.
Perhaps, your user is named staslend.
If programs_for_tryingis a file,
ls -lha /home/staslend/programs_for_trying returns
drwxrwxr-- in rights.

mv /home/staslend/programs_for_trying /home/staslend/tempfile
mkdir /home/staslend/programs_for_trying
cat tempfile

You see contents of your file. I think that you have sources in this file. If that is true, do next:

mv /home/staslend/tempfile /home/staslend/programs_for_trying/file.asm

Make you owner of you directory and its content:

$ sudo chown -R staslend /home/staslend/programs_for_trying/

Make you and your group able to read, rename and write content to it:

$ chmod -R ug+rwx /home/staslend/programs_for_trying/

Make everyone able to read content:

$ chmod -R a+r /home/staslend/programs_for_trying/

NASM on Virtual Machine Ubuntu: Cannot execute binary file exec format error

The error:

error: Cannot execute binary file exec format error

Suggests your system can't understand the executable you are trying to run. In my comments I asked you to run uname -a so that I can find out what type of system you are running in your virtual machine. You gave the output as:

Linux dell 3.16.0-50-generic #67~14.04.1-Ubuntu SMP Fri...i686 i686 i686 GNU/LINUX

The i686 tells us this is a 32-bit version of Ubuntu, not 64-bit. Had the output included x86_64 then you would be on a 64-bit Ubuntu.

A 32-Bit OS can't directly run 64-bit applications. If you need to generate and run 64-bit code you will need to install a 64-bit Ubuntu OS.

A 64-bit Ubuntu system can be configured to allow development of 32 and 64-bit code by using multilib support. If building software with C/C++ (or just the C libraries) it might be useful to install these packages on Ubuntu:

sudo apt-get install gcc-multilib g++-multilib

Assuming you do install a 64-bit OS, the command you use to link your executable appears incorrect. You have:

nasm -f elf64 hello.asm -o hello.o    
ld -o hello.o hello -m elf_x86_64
./hello

The NASM command looks okay. That assembles hello.asm to a 64-bit object file called hello.o . The LD command is being told to generate a 64-bit output file called hello.o from a file called hello. The commands should have looked like:

nasm -f elf64 hello.asm -o hello.o    
ld -o hello hello.o -m elf_x86_64
./hello

Notice that we now use -o hello as we want to output an executable called hello from an object file called hello.o.

How to compile this asm code under linux with nasm and gcc?

If you want to continue using that old book to learn the basics (which is just fine, nothing wrong with learning the basics/old way before moving on to modern OS), you can run it in DOSBox, or a FreeDOS VM.



Related Topics



Leave a reply



Submit