web-dev-qa-db-ja.com

gccはx86アセンブリをコンパイルできますか、それとも単にリンクできますか?

gccはAssemblyを生成できますが、gccまたは他のコンパイラを使用して純粋なAssemblyをコンパイルするにはどうすればよいですか?私はx86アセンブリが難しいことを知っており、私が見ていたMIPSやNiosとは別の命令セットですが、今度は直接x86 asmをコンパイルしてみたいと思います。方法の説明はありますが、Cファイルが含まれており、最初の最も基本的なコンパイルにCファイルは必要ありません。

gcc -o test_asm asm_functions.S test_asm.c

作成するステップがあります.oファイル

gcc -c asm_functions.S
gcc -c test_asm.c
gcc -o test_asm asm_functions.o test_asm.o

しかし、x86 asmをgccで直接コンパイルできるステップがわかりません。 GNU as(GNU Assembler))という名前の別のプログラムがあります。これを使用して、x86アセンブリをマシンコードに変換できますか?

テスト

コード(32.s)

.globl  _start

.text
_start:
        movl    $len, %edx
        movl    $msg, %ecx
        movl    $1, %ebx
        movl    $4, %eax
        int     $0x80

        movl    $0, %ebx
        movl    $1, %eax
        int     $0x80
.data
msg:
        .ascii  "Hello, world!\n"
        len =   . - msg

手順

$ gcc -c 32.s 
$ ls 32*
32.o  32.s
$ gcc -o 32 32.o 
32.o: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'

したがって、32ビットと64ビットが混在しているようですが、アセンブリが32ビット命令か64ビット命令かをコンパイラに通知する必要がありますか?

更新

このテストはgccで機能しました。

$ cat hello.s
.data
.globl hello
hello:
.string "Hi World\n"

.text
.global main
main:
    pushq   %rbp
    movq    %rsp,       %rbp
    movq    $hello,     %rdi
    call    puts
    movq    $0,         %rax
    leave
    ret
$ gcc hello.s -o hello
$ ./hello 
Hi World
20
Niklas

あなたはすでにそれをやっています。

gcc -c asm_functions.S

そのステップにより、オブジェクトファイルasm_functions.oが生成されます。オブジェクトファイルは、マシンコードを含む「リンク可能」ファイル(「ロード可能」ではない)であり、リンカがリンク時にコードを変更する方法に関する追加の指示が含まれています。 gccプログラム自体は単なるドライバーであり、asm_functions.oを生成するために舞台裏でasを実行します。したがって、asを直接実行するオプションがありますが、多くの場合、gccフロントエンドを実行する方が簡単です。

19
Dietrich Epp

更新は機能しますが、元のコードは単にgcc -nostdlib。例えば、

gcc -nostdlib 32.s -o 32 DarrylW
2
Darryl W