🕯️

NASMとGCC(gas)のどちらでもアセンブルできる1つのファイルをつくる

2022/03/06に公開

はじめに

半分ネタです。

NASMとGCC(gas)のどちらでもアセンブルできる1つのファイルをつくってみます。

図で描くと以下です。
helloworld.Sというファイルを用意します。
このファイルはNASM, GCC(gas)でアセンブルできるものです。

使用するnasm, gccのバージョンは以下とします。

$ nasm -v
NASM version 2.14.02
$ gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

以下のリンク先にあるNASM, GCC(gas)用のコードを参考に作成します。

https://cs.lmu.edu/~ray/notes/x86assembly/

作成したファイル

以下のようなファイルを作りました。

helloworld.S
;/*
; nasm -felf64 helloworld.S && ld helloworld.o && ./a.out
; ----------------------------------------------------------------------------------------

          global    _start

          section   .text
_start:   mov       rax, 1                  ; system call for write
          mov       rdi, 1                  ; file handle 1 is stdout
          mov       rsi, message            ; address of string to output
          mov       rdx, 18                 ; number of bytes
          syscall                           ; invoke operating system to do the write
          mov       rax, 60                 ; system call for exit
          xor       rdi, rdi                ; exit code 0
          syscall                           ; invoke operating system to exit

          section   .data
message:  db        "Hello, World NASM", 10      ; note the newline at the end



; gcc -c helloworld.S && ld helloworld.o && ./a.out */
;        .global _start

;        .text
;_start:
;        # write(1, message, 17)
;        mov     $1, %rax                # system call 1 is write
;        mov     $1, %rdi                # file handle 1 is stdout
;        mov     $message, %rsi          # address of string to output
;        mov     $17, %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
;message:
;        .ascii  "Hello, world GCC\n"

ちゃんと、nasm, gccでアセンブルができて、リンク後実行もできます。

$ nasm -felf64 helloworld.S && ld helloworld.o && ./a.out
Hello, World NASM
$ gcc -c helloworld.S && ld helloworld.o && ./a.out
Hello, world GCC

解説

セミコロン;の扱いがnasmとgccで異なります。
nasmではセミコロン以降はコメントとして扱われます。

gccの場合は以下。
区切り文字(?)ということでしょうか。コメントという意味ではないようです。
https://sourceware.org/binutils/docs-2.38/as.html#i386_002dChars

The ‘;’ character can be used to separate statements on the same line.

またgccではC言語のブロックコメント(/*, */)が使用できます

なのでnasmから見ると、下記赤で囲ったところがコードとして見え、
他はコメントとなります。

gccの場合は下記赤枠がコードとして見え、
他はコメントとなります。

感想

「あ、できた」と思ったのが率直な感想です。
あの言語と、あの言語でも似たようなことできるかなとか思いましたが
やってません。

やってよかったことは、ドキュメントをじっくり読めた、ということくらいでしょうか(^^;

追記 c言語とPythonを1つのファイルに書く

hello10.c
#define DUMMY0 /*
for i in range(10):
    print("hello python")

dummy = '''
    # */
#include <stdio.h>
int main(void){ 
    for(int i=0; i<10; i++)
        printf("hello c\n");
    return 0;
}

#define DUMMY1 /*
# '''
# */

実行結果は以下

$ gcc  hello10.c && ./a.out
hello c
hello c
hello c
hello c
hello c
hello c
hello c
hello c
hello c
hello c
$ python3 hello10.c
hello python
hello python
hello python
hello python
hello python
hello python
hello python
hello python
hello python
hello python

Discussion