I've been following this tutorial for an intro to assembly on Linux.
section .text
global _start ;must be declared for linker (ld)
_start:
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptior
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x080 ;call kernel
section .data
msg db 'Hello, world!', 0xa ;the string
len equ $ - msg ;length of the string
I've then had problems compiling it. I've looked around and found (on SO) that I should compile it like this:
nasm -f elf64 hello.asm
gcc -o hello hello.o
But I keep getting this error from GCC:
hello.o: In function `_start':
hello.asm:(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
(NB: I'm running Debian Linux on a 64 bit Intel i7)
If you are going to learn assembly, then you are much better served learning to use the assembler nasm
and the linker ld
without relying on gcc
. There is nothing wrong with using gcc
, but it masks part of the linking process that you need to understand going forward.
Learning assembly in the current environment (generally building on x86_64
but using examples that are written in x86 32-bit
assembler), you must learn to build for the proper target and the language ( syscall
) differences between the two. Your code example is 32-bit
assembler. As such your nasm
compile string is incorrect:
nasm -f elf64 hello.asm
The -f elf64
attempts to compile a 64-bit
object file, but the instructions in your code are 32-bit
instructions. (It won't work)
Understanding and using ld
provides a better understanding of the differences. Rather than using gcc
, you can use nasm
and ld
to accomplish the same thing. For example (with slight modification to the code):
msg db 0xa, 'Hello, StackOverflow!', 0xa, 0xa ;the string
You compile and build with:
nasm -f elf -o hello-stack_32.o hello-stack_32.asm
ld -m elf_i386 -o hello-stack_32 hello-stack_32.o
Note the use of -f elf
for 32-bit
code in the nasm
call and the -m elf_i386
linker option to create a compatible executable.
output:
Hello, StackOverflow!
If you are serious about learning assembler, there are a number of good references on the web. One of the best is The Art of Assembly . (it is written primarily for 8086
and x86
, but the foundation it provides is invaluable). In addition, looking at the executables you create in binary can be helpful. Take a look at Binary Vi (BVI) . It is a good tool.
bvi screenshot
链接二进制文件时,应添加-nostdlib
。
gcc -o hello hello.o -nostdlib
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.