tomyamaのブログ

日記・雑記。

Intel CPUのアセンブラ

MicrosoftのVisual Cに、gdbのようなコマンドラインで使えるデバッガは無いのかな?と思って、コンパイラ(cl.exe)やリンカ(link.exe)が置いてあるフォルダを眺めていたら、アセンブラを発見しました。名前は『ml.exe』です。Intel CPUのアセンブラは全く触った事がないなと思って、興味本位で少し触ってみました。

 

まずは簡単なC言語のコードを書いて、アセンブリコードを出力してみます。なるべく出力されるコードが少なくなるように、最低限のソースコードに留めています。

 

ソースコード

[test.c]

int main( void )
{
    return 0;
}

 

Windows 10, Visual Studio 2022, x86 Native Tools Command Prompt

アセンブル出力

C言語からアセンブリコードに変換してみます。

>cl /Fatest_msvc.asm /c test.c
Microsoft(R) C/C++ Optimizing Compiler Version 19.32.31332 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.c

>

以下のようなアセンブリコードが出力されました。

[test_msvc.asm]

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.32.31332.0 

    TITLE    C:\Users\user\Documents\Intel_x86_assembler\test.obj
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC    _main
; Function compile flags: /Odtp
_TEXT    SEGMENT
_main    PROC
; File C:\Users\user\Documents\Intel_x86_assembler\test.c
; Line 2
    push    ebp
    mov    ebp, esp
; Line 3
    xor    eax, eax
; Line 4
    pop    ebp
    ret    0
_main    ENDP
_TEXT    ENDS
END

C言語と同じようにmainから始まるコードを書けば良いみたいです。オプションで変えられるのかもだけど、何から書けばすら判っていなかったので、判り易いのは有難いです。

 

アセンブラで実行ファイルを出力

先般の発見したアセンブラ(ml.exe)で、アセンブリコードから実行ファイルに変換してみます。

>ml /Fetest_msvc test_msvc.asm
Microsoft (R) Macro Assembler Version 14.32.31332.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: test_msvc.asm
Microsoft (R) Incremental Linker Version 14.32.31332.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/OUT:test_msvc.exe
test_msvc.obj

>

無事に出力できました。

いろいろな開発環境で同じことをやってみて比べてみようと思っていたのですが、ここまでやって気が付きました。例えCPUが同じでも開発環境によってアセンブリコードの描き方は全然違うはず。C言語と違って共通ルール(規格)が無いので。この事に気が付いて、Intel CPUのアセンブラ自体に興味を失いつつあったのですが、最後にgcc,x86だけ試してみました。

 

CentOS Stream 9, gcc (GCC) 11.3.1

アセンブル出力

Visual Studioの時と同様に、まずはC言語からアセンブリコードに変換します。

$ gcc -o test_centos9.s -S test.c 
$

以下のようなアセンブリコードが出力されました。

[test_centos9.s]

    .file    "test.c"
    .text
    .globl    main
    .type    main, @function
main:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size    main, .-main
    .ident    "GCC: (GNU) 11.3.1 20220421 (Red Hat 11.3.1-2)"
    .section    .note.GNU-stack,"",@progbits

Visual Studioと同様に、こちらもmainから始まるコードですね。実行するとmain()関数を見つけ出して実行してくれるのでしょう。C言語のコードを変換しているからこういう出力になっているだけかもしれないけど。

Visual Studioアセンブリコードよりも、謎の行が多いです。

アセンブラを見たり書いたりすると、C言語が【高級言語】と称される理由が実感できます。アセンブラは人間に読み易い構文とは、とても言えないので。。

 

一応、実行ファイルも出力してみました。

 

アセンブラで実行ファイルを出力

$ gcc -o test_centos9 test_centos9.s 
$

 

結論

マイコンのように低レベルなレイヤから開発が必要な時には、アセンブラで記述しなければならない事もあるのですが、OSがある前提のIntel CPUのような環境ではアセンブラに触れる必要は全くありませんね。ブートローダーやOSを開発することなんて、今後も無いでしょうし。。