2
votes

I copied the sample program on assembler and compiled it using gcc, but I got the following output:

gcc hello.s -o hello1

/usr/bin/ld: /tmp/ccPs5dcq.o: relocation R_X86_64_32 against `.data' can not be used when making a PIE object; recompile with -fPIE

/usr/bin/ld: final link failed: nonrepresentable section on output

collect2: error: ld returned 1 exit status

Code:

.data
hello_str:
        .string "Hello, world!\n"
        .set hello_str_length, . - hello_str - 1
.text 
.globl  main
.type   main, @function       
main:
        movl    $4, %eax      
        movl    $1, %ebx      
        movl    $hello_str, %ecx  
        movl    $hello_str_length, %edx 
        int     $0x80         
        movl    $1, %eax      
        movl    $0, %ebx      
        int     $0x80         
        .size   main, . - main    

What am i doing wrong?

P.S. I'm absolutely beginner in assembler, just trying to parse the example

1
Try to compile with -fno-pie. Let me see if I can find a good duplicate for this one.fuz
@fuz thanks, it works, what does it mean?Galina_1960
The instruction movl $hello_str, %ecx needs to know the address of hello_str at link time. This is not the case when creating PIE (position independent) executables, so the linker shouts at you. It is possible to write the same code in a position-independent way, but in 32 bit code, it's a lot more difficult to do, so it's best to ignore this for now. Also, given that you write 32 bit code, you need to assemble and link with -m32 or weird problems are going to occur.fuz
@fuz: Note the R_X86_64_32 relocation: the problem is no support for 32-bit absolute fixups in 64-bit mode. With -m32 the dynamic linker can fixup a 32-bit absolute to hold any pointer in the whole address space, so it is supported. The error message is a duplicate of 32-bit absolute addresses no longer allowed in x86-64 Linux?, except that the real fix is -m32 (and probably also -no-pie is a good idea even if not required).Peter Cordes
If you were compiling as 64-bit code What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code? would also apply.Peter Cordes

1 Answers

2
votes

I had the same issues as OP with gcc and his code, but I can assemble this with the default GNU as with:

as hello.s -o hello.out && ld hello.out -e main -o hello && ./hello

source: https://askubuntu.com/questions/1064619/how-can-i-compile-run-assembly-in-ubuntu-18-04

Another hello world that works is the first example from here.


A possibly a better hello world (thanks to Peter Cordes) that avoids all of this by using lea (still magic to me):

.text

.global main

main:
        # write(1, message, 13)
        mov     $1, %rax                # system call 1 is write
        mov     $1, %rdi                # file handle 1 is stdout
        lea     message(%rip),%rsi      # address of string to output
        mov     $13, %rdx               # number of bytes
        syscall                         # invoke operating system to do the write

        # exit(0)
        mov     $60, %rax               # system call 60 is exit
        xor     %rdi, %rdi              # we want return code 0
        syscall                         # invoke operating system to exit

.section .rodata
message:
        .ascii  "Hello, world\n"

Then you can assemble without errors with:

gcc hello.s -o hello

And run with ./hello

Perhaps worth reading is the list of linux syscalls to see why and what you need to write to get things shown on the terminal.