macOSで「RISC-V」+「ARM64」+「x86_84」の環境をDockerで構築する

# 開発環境
OS: macOS
メモリ: 16GB
プロセッサ: M1

# Docker Desktopを導入する
以下サイトからDocker Desktopをダウンロードしてインストールします。
M１チップなので「Apple Chip」を選択してダウンロードしました。

https://www.docker.com/products/docker-desktop/

# DockerのRozettaをオンにする
DockerのSettingsから「Features in development」を選択して、
「Use Rosetta for x86/amd64 emulation on Apple Silicon」にチェックします。
![docker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34365/3c5bc114-d6ac-7950-5609-cee1754e82ab.png)

# docker-compose.ymlを作成


- 以下のようなディレクトリ配置にして、subsystemディレクトリ直下に「docker-compose.yml」をおきます。
```
subsystem
├── arm64
│   └── test.c
├── riscv64
│   └── test.c
├── x86_64
│   └── test.c
├── docker-compose.yml
├── test.sh
└── install.sh
```

<br>

- docker-compose.ymlの内容は以下の通りにします。
```yaml
version: '3'
services:
  x86_64:
    platform: linux/amd64
    image: amd64/ubuntu:22.04
    tty: true
    volumes:
      - ./x86_64:/x86_64
    ports:
      - "61122:22"
      - "62180:8080"
  arm64:
    platform: linux/arm64/v8
    image: arm64v8/ubuntu:22.04
    tty: true
    volumes:
      - ./arm64:/arm64
    ports:
      - "61222:22"
      - "62280:8080"
  riscv64:
    platform: linux/riscv64
    image: riscv64/ubuntu:22.04
    tty: true
    volumes:
      - ./riscv64:/riscv64
    ports:
      - "61322:22"
      - "62380:8080"
```

<br>

- test.cの内容は以下にします。
```c
#include <stdio.h>

int main(void) {
    int a = 1;
    int b = 2;
    int c = a + b;

    printf("c = %d\n", c);

    return 0;
}
```

<br>

- install.shの内容は以下にします。
```bash
#!/bin/bash

docker exec subsystem-x86_64-1 apt update -y
docker exec subsystem-arm64-1 apt update -y
docker exec subsystem-riscv64-1 apt update -y

docker exec subsystem-x86_64-1 apt install -y git wget curl vim build-essential
docker exec subsystem-arm64-1 apt install -y git wget curl vim build-essential
docker exec subsystem-riscv64-1 apt install -y git wget curl vim build-essential
```

<br>

- test.shの内容は以下のします。
```bash
#!/bin/bash

docker exec subsystem-x86_64-1 bash -c "cd /x86_64 && gcc -c test.c -O2 && objdump -d test.o > test.txt"
docker exec subsystem-arm64-1 bash -c "cd /arm64 && gcc -c test.c -O2 && objdump -d test.o > test.txt"
docker exec subsystem-riscv64-1 bash -c "cd /riscv64 && gcc -c test.c -O2 && objdump -d test.o > test.txt"
```

# C言語のファイルをそれぞれのアーキテクチャのアセンブリに変換してみる。


- まず、install.shを実行して、それぞれのDockerコンテナの開発環境を整えます。
（結構時間がかかります。）
```
bash install.sh
```

<br>

- その次はそれぞれのアーキテクチャのDockerコンテナでtest.cのC言語ファイルをgccでコンパイルします。
```
bash test.sh
```

<br>

- そうするとarm64、riscv64、x84_64ディレクトリに「test.txt」が出力されアセンブラが記述されています。

<br>

- x86_64（アセンブラ）
```

test.o:     file format elf64-x86-64


Disassembly of section .text.startup:

0000000000000000 <main>:
   0:	f3 0f 1e fa          	endbr64 
   4:	48 83 ec 08          	sub    $0x8,%rsp
   8:	ba 03 00 00 00       	mov    $0x3,%edx
   d:	bf 01 00 00 00       	mov    $0x1,%edi
  12:	31 c0                	xor    %eax,%eax
  14:	48 8d 35 00 00 00 00 	lea    0x0(%rip),%rsi        # 1b <main+0x1b>
  1b:	e8 00 00 00 00       	call   20 <main+0x20>
  20:	31 c0                	xor    %eax,%eax
  22:	48 83 c4 08          	add    $0x8,%rsp
  26:	c3                   	ret    
```

<br>

- arm64（アセンブラ）
```

test.o:     file format elf64-littleaarch64


Disassembly of section .text.startup:

0000000000000000 <main>:
   0:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
   4:	52800062 	mov	w2, #0x3                   	// #3
   8:	90000001 	adrp	x1, 0 <main>
   c:	910003fd 	mov	x29, sp
  10:	91000021 	add	x1, x1, #0x0
  14:	52800020 	mov	w0, #0x1                   	// #1
  18:	94000000 	bl	0 <__printf_chk>
  1c:	52800000 	mov	w0, #0x0                   	// #0
  20:	a8c17bfd 	ldp	x29, x30, [sp], #16
  24:	d65f03c0 	ret
```

<br>

- riscv64（アセンブラ）
```

test.o:     file format elf64-littleriscv


Disassembly of section .text.startup:

0000000000000000 <main>:
   0:	1141                	addi	sp,sp,-16
   2:	460d                	li	a2,3
   4:	00000597          	auipc	a1,0x0
   8:	00058593          	mv	a1,a1
   c:	4505                	li	a0,1
   e:	e406                	sd	ra,8(sp)
  10:	00000097          	auipc	ra,0x0
  14:	000080e7          	jalr	ra # 10 <main+0x10>
  18:	60a2                	ld	ra,8(sp)
  1a:	4501                	li	a0,0
  1c:	0141                	addi	sp,sp,16
  1e:	8082                	ret
```

<br>


実機がなくとも、期待する値を得ることができました。
以上です。