I am new to assembly language programming. I write following code,
.text
.globl _start
_start:
movl $1,%eax
movl $0,%ebx
int $0x80
and use as -o JustExit.o JustExit.asm command for creating object file. (Assembly file name is JustExit.asm).
After this step I gave executable permission using,
chmod 777 ./JustExit.o
When I execute program it says,
-su: ./JustExit.o: cannot execute binary file
I am not able to understand why this simple 'exit' program is not working.
Thanks.
Assembling your source through as produces an object file which is "not yet" executable.
You have to link the object file with a linker such as ld, which will then produce a fully working executable (a.out by default).
Your command line chain would look like this:
$ as -o JustExit.o JustExit.asm
$ ld JustExit.o
$ ./a.out
And it works!
Related
I'm getting a weird error message when trying to assemble and run a .s file using AT&T Intel Syntax. Not sure if I'm even using the correct architecture to begin with, or if I'm having syntax errors, if I'm not using the correct commands to assemble and link, etc. Completely lost and I do not know where to begin.
So basically, I have a file called yea.s , which contains some simple assembler instructions. I then try to compile it using the command as yea.s -o yea.o and then link is using ld yea.o -o yea. When running ld, I get this weird message:ld: warning: cannot find entry symbol _start; defaulting to 000000440000.
This is the program im trying to run, very simple and doesn't really do anything.
resMsg: .asciz "xxxxxxxx"
.text
.global main
main:
pushq $0
ret
I just cannot figure out what's going on. Obviously, this is for school homework. I'm not looking for the answer to the homework, obviously, but this is the starting point to where I can actually start the coding. And I just cant figure out how to simple run the program, which it doesn't say in the assignment. Anyway, thanks in advance guys!
Linux executables require an entry point to be specified. The entry point is the address of the first instruction to be executed in your program. If not specified otherwise, the link editor looks for a symbol named _start to use as an entry point. Your program does not contain such a symbol, thus the linker complains and picks the beginning of the .text section as the entry point. To fix this problem, rename main to _start.
Note further that unlike on DOS, there is nothing to return to from _start. So your attempt to return is going to cause a crash. Instead, call the system call sys_exit to exit the program:
mov $0, %edi # exit status
mov $60, %eax # system call number
syscall # perform exit call
Alternatively, if you want to use the C runtime environment and call functions from the C library, leave your program as is and instead assemble and link using the C compiler driver cc:
cc -o yea yea.s
If you do so, the C runtime environment provides the entry point for you and eventually tries to call a function main which is where your code comes in. This approach is required if you want to call functions from the C library. If you do it this way, make sure that main follows the SysV ABI (calling convention).
Note that even then your code is incorrect. The return value of a function is given in the eax (resp. rax) register and not pushed on the stack. To return zero from main, write
mov $0, %eax # exit status
ret # return from function
In all currently supported versions of Ubuntu open the terminal and type:
sudo apt install as31 nasm
as31: Intel 8031/8051 assembler
This is a fast, simple, easy to use Intel 8031/8051 assembler.
nasm: General-purpose x86 assembler
Netwide Assembler. NASM will currently output flat-form binary files, a.out, COFF and ELF Unix object files, and Microsoft 16-bit DOS and Win32 object files.
If you are using NASM in Ubuntu 18.04, the commands to compile and run an .asm file named example.asm are:
nasm -f elf64 example.asm # assemble the program
ld -s -o example example.o # link the object file nasm produced into an executable file
./example # example is an executable file
I'm starting out with programming in Assembly in x86 and I'm following a guide for that. I'm using gas to compile on a linux virtual machine.
I'm trying to run a simple empty program where main routine exits the program immediately. That's the first task in the guide I'm following. My code is saved in a file hello.s and it looks like this:
.global main
main:
movq %rsp, %rbp
mov $0, %rdi
call exit
In the terminal I navigate to the directory of the file and try to run it like this:
gcc -o hello.o hello.s -no-pie ./hello.s
I get an error saying:
/tmp/cc62hr1F.o: In function 'main':
(.text+0x0): multiple definition of 'main'
/tmp/ccwMutY1.o(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
What does this error mean and how to fix it? Thank you in advance.
EDIT/SOLUTION: I figured out what was wrong. In the terminal I should run it like this:
gcc -o hello.o hello.s -no-pie
./hello.o
These are two seperate commands. I wrote them in one line. And the file to run has to have the extensions .o not .s
I'm writing assembly language, program like this:
.data
.equ b,3
.text
.globl _start
_start:
movl $2,%ebx
movl $b,%ecx
movl $1,%eax
int $0x80
I compile it under ubuntu 64bit version. I wish to get a 32bit version, so under shell I can do:
$ as my.s -32
$ ld a.out -o my
OK, no problem. I wish to use scons to manage this process, so I have SConstruct:
Program('my.s')
This will first compile using 'as my.s -o my.o' and 'gcc my.o -o my', and report and error of redefinition of '_start'.
My problem is:
How can I pass '-32' option to make sure I compile out 32bit version object file?
How can I specify the linker to be 'ld' but not 'gcc', to make sure I can use '_start' as entry point in my assembly source file?
For passing flags to the assembler, ASFLAGS should work.
For passing flags to linker, LINKFLAGS should work
For setting which executable to use for linker, LINK (or SHLINK) should do the trick.
All these are listed in the manpage: http://scons.org/doc/production/HTML/scons-man.html
Likely the following should work for you:
env=Environment(tools=['as','gnulink'])
env['ASFLAGS'] = '-32'
env['LINK'] = 'ld'
env.Program('my',['my.s'])
I am very sorry, if my English is bad. This problem is getting me for days.
I have a simple C source code with a sub function which I am examining. First I am creating the .out file with gcc. This file I am examining with GDB. But if I want to disassemble the called function I always get an error message from gdb.
Prolog:
unix#unix-laptop:~/booksrc $ gcc -g stack_example.c
unix#unix-laptop:~/booksrc $ gdb -q ./a.out
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) disass main
Dump of assembler code for function main:
0x08048357 <main+0>: push %ebp
0x08048358 <main+1>: mov %esp,%ebp
0x0804835a <main+3>: sub $0x18,%esp
0x0804835d <main+6>: and $0xfffffff0,%esp
0x08048360 <main+9>: mov $0x0,%eax
0x08048365 <main+14>: sub %eax,%esp
0x08048367 <main+16>: movl $0x4,0xc(%esp)
0x0804836f <main+24>: movl $0x3,0x8(%esp)
0x08048377 <main+32>: movl $0x2,0x4(%esp)
0x0804837f <main+40>: movl $0x1,(%esp)
0x08048386 <main+47>: call 0x8048344 <test_function>
0x0804838b <main+52>: leave
0x0804838c <main+53>: ret
End of assembler dump.
(gdb) disass test_function()
You can't do that without a process to debug.
(gdb)
Do you have an idea for the reason of the error? I have already used google but I can't find anything to solve the problem. I also searched for the instructions to be sure that the syntax is right.
http://visualgdb.com/gdbreference/commands/disassemble
Thanks for reading,
Intersect!
The syntax (of the gdb command) is disass function-name so you should type
disass test_function
Read the genuine GDB documentation.
But you typed wrongly disass test_function() ; then ending parenthesis are wrong.
Be sure that you compiled your source code with gcc -Wall -g
At last, you could ask gcc to output an assembler file. Try for instance to compile your source.c file with
gcc -O1 -S -fverbose-asm source.c
(you could omit the -O1 or replace it with -g if you wanted to)
then look with an editor (or some pager) into the generated source.s assembly file.
Maybe the function isn't there because it was inlined during compilation. I had never seen your error message before, sorry.
Please try to compile with the following additional flags:
-O0 -g
You can also see all function start addresses with:
objdump -x <filename>
This gives you a list of symbols in your executable file which includes all the start points of functions.
You can also disassemble your code with:
objdump -d <filename>
I'm currently trying to learn assembly on my Trisquel distribution (which I guess uses Ubuntu under the hood?). For some reason, I'm stuck on the very first step of creating and executing a assembly snippet.
.section data
.section text
.globl _start
_start:
movl $1, %eax # syscall for exiting a program
movl $0, %ebx # status code to be returned
int $0x80
When I try to assemble and link it for creating an executable and run the executable, I get something like:
> as myexit.s -o myexit.o && ld myexit.o -o myexit
> ./myexit
bash: ./myexit: cannot execute binary file
I'm not sure what exactly is going on here. After searching around, it seems that this error usually pops up when trying to execute 32 bit executable on a 64 bit OS or maybe vice-versa which isn't the case for me.
Here is the output of file and uname command:
$ file myexit
myexit: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
$ uname -a
Linux user 2.6.35-28-generic #50trisquel2-Ubuntu SMP Tue May 3 00:54:52 UTC 2011 i686 GNU/Linux
Can someone help me out in understanding what exactly is going wrong here? Thanks.
.section text
is incorrect, that creates a section called text when you need your code to be in the .text section. Replace that with:
.data
.text
.globl _start
_start:
...