もっとCPUの気持ちが知りたいですか? - @ledsun blog で、本の環境と自信の環境で生成されるアセンブリファイルの命令が異なることに気がつきました。
X86アセンブラ/GASでの文法 - Wikibooks によると
というものがあるそうです。
オペレーションサフィックス 「pushl」とか「movl」とか、プッシュ命令やムーブ命令のうしろにエル「l」がサフィックスです。
データサイズなどを指定するためにサフィックスを指定する必要がある。
GASのアセンブリ命令では、一般にオペランドがどのサイズのデータを扱うか指定するために、b、s、w、l、q、tのいずれかの文字をオペランドの最後に付ける。これをサフィックスという。
ということは、もしかしてCPUアーキテクチャの違いではなく、コンパイラの違いなのでしょうか? clangで試してみます。
sudo apt install clang
してclangをインストールします。
つぎにclang -S calc1.c
を実行して、アセンブリファイルを作成します。
.text .file "calc1.c" .globl main # -- Begin function main .p2align 4, 0x90 .type main,@function main: # @main .cfi_startproc # %bb.0: pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset %rbp, -16 movq %rsp, %rbp .cfi_def_cfa_register %rbp subq $32, %rsp movl $0, -4(%rbp) movl %edi, -8(%rbp) movq %rsi, -16(%rbp) movl $1, -20(%rbp) movl $2, -24(%rbp) movl -20(%rbp), %eax addl -24(%rbp), %eax movl %eax, -28(%rbp) movl -28(%rbp), %esi leaq .L.str(%rip), %rdi movb $0, %al callq printf@PLT xorl %eax, %eax addq $32, %rsp popq %rbp .cfi_def_cfa %rsp, 8 retq .Lfunc_end0: .size main, .Lfunc_end0-main .cfi_endproc # -- End function .type .L.str,@object # @.str .section .rodata.str1.1,"aMS",@progbits,1 .L.str: .asciz "c = %d\n" .size .L.str, 8 .ident "Ubuntu clang version 14.0.0-1ubuntu1" .section ".note.GNU-stack","",@progbits .addrsig .addrsig_sym printf
movlやmovqが出てきます。 セクション名や行の順番がちがうけど、mainの中身は一緒でしょうか? diffを見てみます。
1,5d0 < .file "calc1.c" < .text < .section .rodata < .LC0: < .string "c = %d\n" 7,10c2,6 < .globl main < .type main, @function < main: < .LFB0: --- > .file "calc1.c" > .globl main # -- Begin function main > .p2align 4, 0x90 > .type main,@function > main: # @main 12c8 < endbr64 --- > # %bb.0: 15c11 < .cfi_offset 6, -16 --- > .cfi_offset %rbp, -16 17c13 < .cfi_def_cfa_register 6 --- > .cfi_def_cfa_register %rbp 19,36c15,33 < movl %edi, -20(%rbp) < movq %rsi, -32(%rbp) < movl $1, -12(%rbp) < movl $2, -8(%rbp) < movl -12(%rbp), %edx < movl -8(%rbp), %eax < addl %edx, %eax < movl %eax, -4(%rbp) < movl -4(%rbp), %eax < movl %eax, %esi < leaq .LC0(%rip), %rax < movq %rax, %rdi < movl $0, %eax < call printf@PLT < movl $0, %eax < leave < .cfi_def_cfa 7, 8 < ret --- > movl $0, -4(%rbp) > movl %edi, -8(%rbp) > movq %rsi, -16(%rbp) > movl $1, -20(%rbp) > movl $2, -24(%rbp) > movl -20(%rbp), %eax > addl -24(%rbp), %eax > movl %eax, -28(%rbp) > movl -28(%rbp), %esi > leaq .L.str(%rip), %rdi > movb $0, %al > callq printf@PLT > xorl %eax, %eax > addq $32, %rsp > popq %rbp > .cfi_def_cfa %rsp, 8 > retq > .Lfunc_end0: > .size main, .Lfunc_end0-main 38,57c35,45 < .LFE0: < .size main, .-main < .ident "GCC: (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0" < .section .note.GNU-stack,"",@progbits < .section .note.gnu.property,"a" < .align 8 < .long 1f - 0f < .long 4f - 1f < .long 5 < 0: < .string "GNU" < 1: < .align 8 < .long 0xc0000002 < .long 3f - 2f < 2: < .long 0x3 < 3: < .align 8 < 4: --- > # -- End function > .type .L.str,@object # @.str > .section .rodata.str1.1,"aMS",@progbits,1 > .L.str: > .asciz "c = %d\n" > .size .L.str, 8 > > .ident "Ubuntu clang version 14.0.0-1ubuntu1" > .section ".note.GNU-stack","",@progbits > .addrsig > .addrsig_sym printf
ああ、パラメーターとかも微妙に違うんですね。