Compile/run assembler in Linux?

后端 未结 8 1792
清歌不尽
清歌不尽 2020-12-22 18:05

I\'m fairly new to Linux (Ubuntu 10.04) and a total novice to assembler. I was following some tutorials and I couldn\'t find anything specific to Linux. So, my question is,

8条回答
  •  死守一世寂寞
    2020-12-22 18:28

    The GNU assembler is probably already installed on your system. Try man as to see full usage information. You can use as to compile individual files and ld to link if you really, really want to.

    However, GCC makes a great front-end. It can assemble .s files for you. For example:

    $ cat >hello.s <<"EOF"
    .section .rodata             # read-only static data
    .globl hello
    hello:
      .string "Hello, world!"    # zero-terminated C string
    
    .text
    .global main
    main:
        push    %rbp
        mov     %rsp,  %rbp                 # create a stack frame
    
        mov     $hello, %edi                # put the address of hello into RDI
        call    puts                        #  as the first arg for puts
    
        mov     $0,    %eax                 # return value = 0.  Normally xor %eax,%eax
        leave                               # tear down the stack frame
        ret                            # pop the return address off the stack into RIP
    EOF
    $ gcc hello.s -no-pie -o hello
    $ ./hello
    Hello, world!
    

    The code above is x86-64. If you want to make a position-independent executable (PIE), you'd need lea hello(%rip), %rdi, and call puts@plt.

    A non-PIE executable (position-dependent) can use 32-bit absolute addressing for static data, but a PIE should use RIP-relative LEA. (See also Difference between movq and movabsq in x86-64 neither movq nor movabsq are a good choice.)

    If you wanted to write 32-bit code, the calling convention is different, and RIP-relative addressing isn't available. (So you'd push $hello before the call, and pop the stack args after.)


    You can also compile C/C++ code directly to assembly if you're curious how something works:

    $ cat >hello.c <
    int main(void) {
        printf("Hello, world!\n");
        return 0;
    }
    EOF
    $ gcc -S hello.c -o hello.s
    

    See also How to remove "noise" from GCC/clang assembly output? for more about looking at compiler output, and writing useful small functions that will compile to interesting output.

提交回复
热议问题