OmniAICreator/Qiita-1.07M huggingface dataset:
GitHubのデフォルトブランチの変更およびdevelop/masterへの直pushの禁止

# デフォルトブランチをdevelopに変更 
1. SettingsタブのDefault branch欄で矢印押下 
1. 確認ダイアログのdevelop選択、Update押下
1. 確認ダイアログのI Understand, update the default branch押下

# develop/masterへの直pushの禁止
1. Settingsタブの左メニューのBranches押下
1. Add classic branch protection rule押下
1. Branch name patternにdevelop入力、以下をチェックしてCreate押下
    - Require a pull request before merging
    - Do not allow bypassing the above settings
    - Restrict who can push to matching branches
    - Restrict that create matching branches
1. Add rule押下
1. Branch name patternにmaster入力、developと同じものをチェックしてCreate押下

自分のPRを自分でdevelopにマージできるようにRequire approvalsはチェックしていない

# 直push禁止の確認
```bash
git clone https://github.com/XXX/XXX.git
cd XXX
git checkout -b temp-branch
echo "XXX" > dummy.txt
git add .
git commit -m "XXX"
git push origin HEAD:develop
git push origin HEAD:master
```
pushがエラーになればOK
MIT App Inventorで通知使ってみた！！

### はじめに
MIT App Inventorで通知を表示させてみます！デフォルトでnotifierがありますが，スクリーン中央にのみ表示できます．これでは一般的なアプリの様なスクリーン上部からの通知を実装することができない．ここでは，「Notification Style」を用いいることで，より実際のアプリに似た動作ができるので，ここにメモとして残します！

:::note info
### 詳しくは
[Notification Styleについて](https://github.com/jarlisson2/NotificationStyleAIX)
>About
The Notification Style extension carries many built-in notification features like BigText, LargeIcon, BigPicture, SmallIcon, MediaStyle, MessageStyle. That way, you won't be so limited in talking to the user.
:::

:::note info
### できること
通知を実際のアプリのように**ロック画面やステータスバー，通知センター**に表示させることができるようになります．
アプリ使用中でなくても，ユーザーに情報を与えられるようになるので，アプリの幅が広がることでしょう！

左からロック画面，通知センター，通知，アイコンに通知数の表示

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/33dcf4c1-6584-45e4-824a-7f70b8480a89.jpeg" width = 23% >

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/da032366-4cff-4d75-a7b4-e30e1ed251d9.jpeg" width = 23%>

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/465b3c1c-fe6a-48fa-9ef4-7be8b8d330f7.jpeg" width=23% >

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/d174e224-a538-4c72-8f14-7e8bd4c5f4c5.jpeg width = 23%>

:::

### 主な通知について

#### call Notification Style1. Simple Notification
一番シンプルな通知方法．色々なアプリでよく目にする通知です．

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/d23c6be4-5933-4c2e-ab68-4bfd693c5091.png width = 40%>
<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/d9332c59-3cc4-4ba4-99e0-ced030f7a842.jpeg width = 40%>


#### call Notification Style1. Action Notification
通知にボタンを含むことができる．アプリを開かなくても，リアクションができる点で便利そうです．
ボタンを使用する際には，ブロックのlist Buttonsにリスト形式でボタンに表示させたいテキストを入れます．通知の右側にアイコンも表示しています．

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/9aa99bf2-e512-4282-94f6-82d6942dc4ea.png width = 40%>
<img src =https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/770b77fd-08fc-4e88-82cc-4a6609a1d1f8.jpeg width = 40%>

#### call Notification Style1. Big Picture Notification
通知で画像を表示させることができます．日常では見ることが少ない気がします．

<img src =https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/997b8ffe-0760-4913-9d45-d06abd24865a.png width = 40%>
<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/2678448b-09f6-4c60-88be-dab323f60509.jpeg width = 40%>

#### call Notification Style1. Large Icon Notification
通知の右側にアイコンを表示させます．

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/92f8a57f-bddf-4bbf-ac1d-e9ec6e63ab58.png width = 40% >
<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/160dc1b9-0df9-41b7-a7ef-54df3893be66.jpeg width = 40%>



#### call Notification Style. Receive Massage Notification
通知から返信できるものです！！

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/ee3ad5ae-1d02-40b8-afbb-f63e15f87e15.png width = 40%>
<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/629547b6-19b8-4bb8-8414-d477190b2eb5.jpeg width = 40%>


### おわりに
これが使用できることでより一層，アプリらしいものが作れるようになりそうです．
Powershellでnpmがあるかどうかを確認する方法～psの権限についても調べてみた～

# 現象
WindowsにLTS版のNode.jsを入れて作業しているとき、
バージョン管理ツールなどを特に用いてないため、今どんなバージョンなのか
知ろうとして、`npm -v`で確認しようとしました。

すると、なぜかバージョンを確認できない状態に...。

```
npm : ファイル C:\Program Files\nodejs\npm.ps1 を読み込めません。ファイル C:\Program Files\nodejs\npm.ps1 はデジタル署名されていませ
ん。このスクリプトは現在のシステムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Po
licies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
```
Node.jsが入っていてnpmがないことはありえないので、なんだろう～と思っていたところ、Powershellで開いていたこと、かつ、参照する権限がないことが原因だったようです。

スタートボタンからcmdを検索してそこから`npm -v`を試すと、すぐに見つけてくれました。

しかし、折角なのでPowershellでもnpm.ps1を確認する方法をまとめておきます。

# 実行ポリシーについて
上記のエラーにもある通り、npmを参照することはセキュリティ的に制限されているようです。そもそも、実行ポリシー（ここでは`ExecutionPolicy`と呼称します）は主に６つの種類によって分けられています。

### ExecutionPolicyの種類
| Restricted（制限付き） | AllSigned（すべて署名済み） | RemoteSigned（リモート署名済み）| Unrestricted（無制限） | Bypass（バイパス） | Undefined（未定義）|
|----|----|----|----|----|----|
|デフォルト設定| 信頼できる発行元に署名されたスクリプトのみ実行可能 | ローカルで作成したスクリプトは署名なしで実行可能| すべてのスクリプトを実行可能 | すべてのスクリプトを警告なしで実行 | 現在のスコープに設定がない |
| 対話モードのみ使用可能 PowerShellスクリプトの実行を完全に禁止 | スクリプトにデジタル署名が必要 | ローカルで作成したスクリプトは署名なしで実行可能 | 危険なスクリプトを実行する前に警告が表示される| セキュリティ上のリスクが高い | 親スコープからポリシーを継承 |


ExecutionPolicyはそれぞれ異なるスコープ別に設定することが可能です。

### ExecutionPolicyのレベル別設定
| Process | CurrentUser | LocalMachine | UserPolicy | MachinePolicy |
|----|----|----|----|----|
| 現在のPowerShellセッションのみ（終了すると失効） | 現在のユーザーのみ | コンピュータ上のすべてのユーザー | Group Policyで設定されたユーザーポリシー | Group Policyで設定されたコンピュータポリシー |



設定内のGroup Policyとは、`Windows環境内でのユーザーとコンピューターの設定を一元管理するためのシステム`です。IT管理者が、組織全体のスコープレベルを設定する際などに使われそうですね（興味ありますがここについては割愛）。


# 一時的に実行ポリシーを変更する
さて、npmをPowershellで参照するために一時的にExecutionPolicyを変更します。
以下のようなコマンドを打てば変更できます。

```
// 現在開いているshell内のみで警告なしにscriptを実行可能にする
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```

永続的に権限を変更したい場合、管理者権限で開いて以下のコマンドを実行します。
```
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
```
`CurrentUser`は個人利用の場合では基本的に１ユーザーのみですので、警告と署名もなしに実行できるということになりますね。

組織レベルになってくると、上記に記載した`Group Policy`の設定が関わってくるのですが、このレベルを知っていても社内では操作できない（してはいけない）と思うので、Powershellのデフォルトと設定可能な権限は上記を理解していれば十分な気がします。

さて、npmをPSで参照するという、大して意味をなさない、というか勘違いから生まれた調査ですが、windowsのコマンドについて少し理解ができました。

予期せぬ発見は、こういうところから生まれるかもしれませんね！
対処法：Appleは、“~"にMacに損害を与えたり、プライバシーを侵害する可能性のあるマルウェアが含まれていないことを検証できませんでした。

# 背景
MacOSでアプリケーションをダウンロードした後、『実行しようとしたら開けない❗️』ということが毎回あり、その都度、起動の方法を調べるということを繰り返していたので、解決法をメモしたものです🧐

![スクリーンショット 2025-05-12 15.08.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/55d04b35-5827-41bb-a00f-581af06d0943.png)

# プライバシーとセキュリティを開きましょう
『お使いのMacを保護するために"OpenVisualTraceroute.app"がブロックされました』の横にある『このまま開く』から起動することができる。
![スクリーンショット 2025-05-12 15.09.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/033cf6f9-c336-4940-8369-87119f2bc013.png)
![スクリーンショット 2025-05-12 15.10.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/2f1c8f0a-cd37-4982-9ccf-f822696e9104.png)
![スクリーンショット 2025-05-12 15.10.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/e9851fce-f855-405f-b409-6d18cd1d3462.png)

# 注意書き
ダウンロードしたアプリケーションが信頼できるものであることを確認してから起動してください。
HerokuアプリにGitHubからのAutoDeployを設定

[Heroku GitのmasterブランチをGitHubのdevelopブランチに強制上書き](https://qiita.com/pilot/items/ea560ff9adae5aaad5cb)の続き

ここでのHerokuアプリはOrganization Appである前提

1. Herokuの当該アプリの画面を開く
1. DeployタブのDeployment method欄でGitHubを選択してConnect to GitHub押下 
1. Organization accessの＜組織名＞のRequest押下、確認ダイアログのRequest approval from owners押下
→ GitHubの当該組織のオーナーに承認依頼メールが送られる (誰がオーナーなのかは当該GitHubリポジトリ画面のPeopleタブで確認できる)
1. (ここでメールを受信したオーナーはメール内のリンクからGitHub画面にアクセスし、Grant Access押下で承認)
1. 再度DeployタブのDeployment method欄でGitHubを選択してConnect to GitHub押下
1. ＜組織名＞にチェックマークがついたことを確認してAuthorize heroku押下
1. Connect to GitHub欄で＜組織名＞を選択して対象リポジトリを検索し、Connect押下
1. Automatic deploys欄で対象ブランチを選択し、Enable Automatic Deploys押下
1. 初回はManual deploy欄で対象ブランチを選択し、Deploy Branchを押下
いろんなアルゴリズム"00.00.00.15"

[知恵の館の目次](https://qiita.com/rionQ/items/0ba7a700620a1d617bc6)
# 立ち位置・仕様
* いろんなアルゴリズムをコピペできるように記録するのみ
* 最適化が目的でない
* たまにメモとして解説を残す
* 最低限でまとめる
* データを抽出しやすいように個別のIDを付与
* あるアルゴリズムにおいて、他のアルゴリズムが登場する際にはそのIDを付与
* IDは16進数表記
* なるべく最低限なパッケージで実装
* なるべく特殊なオブジェクト型は使用しない

# TargetID
00.00.00.15

# ReferenceID

# run length decoding
* 可逆圧縮

```python:
def runLengthDecoding(l):
	string = ""
	for key, num in l:
		string += num*key
	return string
```

# 使用方法
```python:
l = [('a', 3), ('b', 4), ('c', 1), ('d', 3), ('e', 1)]
string = runLengthDecoding(l)
print(string) # aaabbbbcddde
```
スタックアセンブリ：Hello World without libc



> _"依存を排せ。世界を構築するとは、自らの足元を知ることから始まる。"_  

あなたの書いた「Hello, World!」は、  
本当にあなたのものだろうか？

それは、Cランタイムが整えた世界の上に、  
無数の関数と抽象が重ねられた結果にすぎないのではないか？

**この章は、そのすべてを捨てることから始まる。**

libcに依らず、リンカに依らず、OSすら最小限に頼り、  
**スタックとレジスタのみによって世界を構築する**。

それが「スタックアセンブリ」による、最小の“Hello, World”。

---

## 前提：libc なしとはどういうことか

通常、C言語で書かれたプログラムは、以下に依存している：

- スタートアップルーチン（`_start` → `main`）  
- 標準入出力ライブラリ（`printf`, `puts`）  
- メモリアロケーション（`malloc`, `free`）  
- グローバル変数の初期化と破棄

つまり、`int main()`を書いた時点で、  
**すでに100KB以上の依存物を呼び出している**。

この章の目標は：

- これらを**すべて排除する**  
- 自分の手で「開始」と「終了」を設計する  
- 「文字を表示する」とは**物理的に何が起きているか**を理解する

ということにある。

---

## 方法：最小構成での write syscall 利用

Linuxにおいて、`write(1, buffer, size)` は、  
**標準出力に任意のバイト列を書き出す**ことを意味する。

これを使えば、Cもprintfも不要だ。

必要な構成要素：

- `.text`セクション：エントリポイント`_start`  
- `.data`セクション：表示するメッセージ  
- `rax/rdi/rsi/rdx`のレジスタ配置  
- `syscall`命令  
- `exit`の明示

---

## コード例：libc なし “Hello, world!”

```nasm
section .data
    msg db "Hello, world!", 0xA
    len equ $ - msg

section .text
    global _start

_start:
    ; write(1, msg, len)
    mov     rax, 1      ; syscall: write
    mov     rdi, 1      ; file descriptor: stdout
    mov     rsi, msg    ; pointer to message
    mov     rdx, len    ; length of message
    syscall

    ; exit(0)
    mov     rax, 60     ; syscall: exit
    xor     rdi, rdi    ; status: 0
    syscall
```

### ビルドと実行

```bash
nasm -f elf64 hello.asm -o hello.o
ld -o hello hello.o
./hello
```

これで、**完全に libc 非依存の Hello World が完成**する。

---

## スタックはどう使われているのか？

ここであえて**スタック操作を導入**してみよう。

```nasm
section .text
    global _start

_start:
    sub     rsp, 32     ; スタック確保（アライメント確保）
    mov     rax, 1
    mov     rdi, 1
    lea     rsi, [rel msg]
    mov     rdx, msglen
    syscall

    mov     rax, 60
    xor     rdi, rdi
    syscall

section .data
    msg db "Hello from the stack.", 0xA
    msglen equ $ - msg
```

ここで重要なのは、  
**“スタックを安全に操作しながら syscall を行う”**という点。

- `sub rsp, 32` は `syscall` 前の16バイト境界アライメントの慣例  
- `lea rsi, [rel msg]` によってセグメント超えを防ぐ

スタックの設計は、  
単なる退避領域ではない。  
それは**「一時的な宇宙」**であり、制御とデータの両方を包摂する構造だ。

---

## さらに一歩：msg 自体をスタック上に構築する

```nasm
section .text
    global _start

_start:
    sub     rsp, 32
    mov     rbx, rsp
    mov     dword [rbx], 0x0A21646C  ; 'ld!\n'
    mov     dword [rbx+4], 0x726F7720 ; ' wor'
    mov     dword [rbx+8], 0x6F6C6C65 ; 'ello'

    mov     rax, 1
    mov     rdi, 1
    mov     rsi, rbx
    mov     rdx, 13
    syscall

    mov     rax, 60
    xor     rdi, rdi
    syscall
```

この例では、**文字列ですらデータセクションを使わず、スタック上に構築している**。  
これは、“自己完結性”の極致であり、  
**「構造の中に意味を畳み込む」**という設計思想の表現である。

---

## スタックアセンブリがもたらすもの

1. **理解の透明性**  
   - 何が使われ、何が破棄され、何が残るのかすべてが見える

2. **最小限の設計哲学**  
   - 使わないものは持ち込まない。書かないことが構造になる。

3. **自己完結性の美学**  
   - メモリ空間、実行単位、終了まで、すべて自前で用意できる

4. **ライブラリとランタイムからの独立**  
   - 世界を構築する“最初の設計者”としての立場を取り戻せる

---

## 結語：Hello Worldは、世界の宣言である

`printf("Hello, world!");` は便利だ。  
だがその便利さは、**すべてを隠すという代償の上に成り立っている。**

スタックアセンブリは、  
その隠された全てを、**一命令ずつ明かしていく設計行為**である。

- 世界を知るために  
- 意志を刻むために  
- 設計とは何かを取り戻すために

あなたの「Hello」は、自分の設計であるべきだ。

> _"Hello, world." それは、世界の上に自分が立ったことを、たった一度だけ証明する言葉である。_
システムコールを手書きするLinuxアセンブリ



> _"ユーザー空間で見えているものは、すべて幻想である。現実は、割り込み命令とカーネルの向こうにある。"_  

現代のプログラミングでは、ファイル操作も画面出力も、すべて「ライブラリ」や「API」を通じて行われている。

しかし、**その奥にある本質的な操作**は、すべて  
**カーネルに対する「システムコール（System Call）」という儀式**を経て実現されている。

この章では、アセンブリを用いて、  
Linuxにおける「手書きシステムコール」実装の実例を通し、  
**人間とカーネルの最も根源的な接点**を明らかにする。

---

## システムコールとは何か？

ユーザー空間のプロセスは、  
直接ハードウェアやリソースにアクセスすることはできない。

代わりに、OSカーネルに対して**特権操作の“依頼”を行う**。  
これが、**システムコール（syscall）**である。

例：

- `write(fd, buffer, size)`  
- `open(path, flags)`  
- `exit(status)`

これらは、実際には以下のようなフローで処理される：

1. ユーザー空間でレジスタに引数をセット  
2. 特定の割り込みや命令（`int 0x80`, `syscall`）を発行  
3. カーネル空間へ制御移譲  
4. カーネルが処理し、結果を返す

---

## x86_64におけるシステムコール規約

Linuxの64bit環境では、`syscall`命令と**特定レジスタへの引数配置**が必要。

| 引数位置 | 使用レジスタ |
|-----------|---------------|
| syscall番号 | `rax` |
| 第1引数 | `rdi` |
| 第2引数 | `rsi` |
| 第3引数 | `rdx` |
| 第4引数 | `r10` |
| 第5引数 | `r8` |
| 第6引数 | `r9` |
| 戻り値 | `rax` |

このルールを知っていれば、ライブラリなしでも**直接システムコールを発行できる。**

---

## 例：write(1, message, 13) を手書きで行う

```nasm
section .data
    msg db "Hello, syscalls", 0xA
    len equ $ - msg

section .text
    global _start

_start:
    mov rax, 1          ; syscall番号 1 = write
    mov rdi, 1          ; fd = stdout
    mov rsi, msg        ; バッファのアドレス
    mov rdx, len        ; バイト数
    syscall             ; カーネルに呼び出し

    ; exit(0)
    mov rax, 60         ; syscall番号 60 = exit
    xor rdi, rdi        ; exit code = 0
    syscall
```

ビルドと実行：

```bash
nasm -f elf64 syscall.asm -o syscall.o
ld syscall.o -o syscall_demo
./syscall_demo
```

このプログラムは、**Cライブラリなしで`write()`を直叩き**している。  
つまり、**OSに最も近いレイヤーで「Hello, syscalls」と叫んでいる。**

---

## なぜ手書きするのか？

### 1. ランタイムの理解

普段呼んでいる関数が、  
どのようにOSと対話しているかを正確に理解できる。

### 2. リンクレスなバイナリを作れる

`libc`不要の超小型プログラムが構築できる。  
これは、**静的解析・攻撃回避・OS自作などに有効**。

### 3. セキュリティ／逆アセンブル観点で必須の知識

マルウェア、シェルコード、ROPチェーンなどは、  
この「手書きsyscall」で実装される。

つまり、**最も純粋な形式の“設計”でもある。**

---

## 他の代表的なシステムコール番号（x86_64）

| 機能 | syscall番号 |
|------|-------------|
| `read` | 0 |
| `write` | 1 |
| `open` | 2 |
| `close` | 3 |
| `exit` | 60 |
| `getpid` | 39 |
| `execve` | 59 |

ソース：`/usr/include/x86_64-linux-gnu/asm/unistd_64.h`

これらの知識があると、  
**任意のプログラムをシステムレベルで「再構築」できる**。

---

## syscall命令の裏側：なぜそれで「切り替わる」のか？

`syscall`命令は：

- カーネルが用意した**MSR（Model-Specific Registers）**に従い  
- CPUリングレベル（ユーザー: Ring 3 → カーネル: Ring 0）を移行  
- `CS`, `SS`, `RSP` などが強制的に切り替わる

つまり、これは単なる関数呼び出しではなく、**CPU特権の変更＝世界の境界線**なのだ。

---

## 結語：システムコールは設計者の祈りである

手書きのシステムコールは、  
一見してプリミティブで、時代遅れに見えるかもしれない。

だがそこには：

- 制御を委ねるという信頼  
- 知識で抽象を貫く力  
- 世界に“直接”語りかける設計者の声

が宿っている。

> _"高級言語は世界を隠すが、システムコールは世界の境界を指し示す。設計者が世界を知ろうとするなら、最初の一声は、このsyscallであるべきだ。"_
自作ブートローダを書く：BIOSとの最初の会話



> _"全ての設計は、最初の512バイトから始まる。"_  

OSを起動するという行為は、  
実はソフトウェアにとって最も物理に近い儀式である。

ボタンが押され、電源が入り、BIOSが動き出し、  
そして、**「最初の512バイト」が読み込まれる。**

それが、**ブートローダ（Bootloader）**だ。

この章では、アセンブリによる最小構成のブートローダを通して、  
**BIOSという先史時代の遺産との対話**を開始しよう。

---

## ブートローダとは何か？

ブートローダとは：

- 電源投入後、最初に実行されるユーザー定義コード  
- BIOSやUEFIから制御を受け取り、OSカーネルへと制御を渡す

存在である。

x86の伝統的ブートシーケンスでは：

1. BIOSがハードウェア初期化を行う（POST）  
2. デバイスからMBR（Master Boot Record）を読み込む  
3. MBRの先頭512バイトを物理アドレス`0x7C00`にロード  
4. そこからコード実行を開始する

**つまり、自作OSの最初の命令は、このMBRにある**。

---

## MBRの制約と要件

### サイズ：512バイト固定

- BIOSは**セクタ単位（512バイト）**で読み込む
- この制限の中で、コード＋ブートシグネチャを収める必要がある

### ブートシグネチャ：0x55AA

- MBRの**末尾2バイト**（`0x1FE`, `0x1FF`）に`0x55`と`0xAA`がなければ、  
  BIOSはそのセクタを「ブートローダ」と認識しない

### 実行環境：リアルモード（Real Mode）

- 16bit  
- セグメント:オフセットアドレッシング  
- レジスタ：AX, BX, CX, DX, SI, DI, SP, BP + セグメントレジスタ  
- 直接扱えるメモリ：1MB未満

この条件の中で、**最初の意志＝ブートローダ**を書く必要がある。

---

## 最小構成のブートローダ（例）

以下は「画面に文字を1つ表示してハルトする」ブートローダの例：

```nasm
[BITS 16]
[ORG 0x7C00]

start:
    mov ah, 0x0E       ; テレタイプ出力機能（BIOSサービス）
    mov al, 'A'        ; 出力文字
    int 0x10           ; BIOS割り込みで文字出力
    cli                ; 割り込み禁止
    hlt                ; ハルト（止まる）

times 510 - ($ - $$) db 0 ; パディング
dw 0xAA55               ; ブートシグネチャ
```

この512バイト（実際は数十バイト）は：

- BIOSが読み込み  
- 実行を開始し  
- レジスタや割り込みを通じて、物理デバイスと通信している

つまりこれは、**「設計者が世界と最初に交わす会話」**である。

---

## ビルドと書き込み：自作ブートローダの起動

NASMなどのアセンブラでビルド：

```bash
nasm -f bin bootloader.asm -o boot.img
```

仮想マシンで起動（QEMUなど）：

```bash
qemu-system-i386 -fda boot.img
```

この1文字の表示に、設計思想、物理空間、そして歴史が詰まっている。

---

## BIOSという「幽霊」との対話

BIOSは今や過去の遺産と化しつつある。  
だが、その影響力は根強い。

- ブート時の割り込み呼び出し（INT 0x10, 0x13など）  
- 16bit環境前提の命令体系  
- MBR構造

これらは、現代のUEFIが台頭した今も、**エミュレーションや互換層として生きている**。

ブートローダを書くという行為は、  
**この幽霊たちと対話し、自らの意志を通すという構造的交渉**なのだ。

---

## なぜブートローダを書くのか？

1. **自作OS開発の起点として**  
2. **アーキテクチャ理解のための実験として**  
3. **コンピュータが何をどう始めるのかを知るために**  
4. **制約下で設計する力を鍛えるために**

そして何より、  
**すべてのソフトウェアの“原初の1命令”がここにある**からだ。

---

## 結語：512バイトに込められた意志

ブートローダは、わずか512バイトしかない。  
だがそこには、

- 世界の立ち上げ  
- 意志の伝播  
- 設計者の声

が詰まっている。

何かを作るとは、世界に介入すること。  
そしてその最初の接触点が、ブートローダである。

> _"OSを起動するとは、世界を一から立ち上げることであり、そのすべては、512バイトという小さな宇宙に始まる。"_
いろんなアルゴリズム"00.00.00.14"

[知恵の館の目次](https://qiita.com/rionQ/items/0ba7a700620a1d617bc6)
# 立ち位置・仕様
* いろんなアルゴリズムをコピペできるように記録するのみ
* 最適化が目的でない
* たまにメモとして解説を残す
* 最低限でまとめる
* データを抽出しやすいように個別のIDを付与
* あるアルゴリズムにおいて、他のアルゴリズムが登場する際にはそのIDを付与
* IDは16進数表記
* なるべく最低限なパッケージで実装
* なるべく特殊なオブジェクト型は使用しない

# TargetID
00.00.00.14

# ReferenceID

# run length encoding
* 可逆圧縮
```python:
def runLengthEncoding(string):
	ol = []
	char1 = string[0]
	count = 1
	for i in range(1,len(string)):
		char2 = string[i]
		if char1 == char2:
			count += 1
		else:
			ol.append((char1, count))
			char1 = char2
			count = 1
	ol.append((char1, count))
	return ol
```

# 使用方法
```python:
string = "aaabbbbcddde"
l = runLengthEncoding(string)
print(l) # [('a', 3), ('b', 4), ('c', 1), ('d', 3), ('e', 1)]
```
ハードウェアに近いとはどういうことか？



> _"動くものを書く。それは、動かすものと向き合うことから始まる。"_  

「このコードはハードウェアに近い」  
そう語られることがある。  

だが、**“近い”とは一体何を意味するのか？**

- 制御レジスタを直接叩くことか？  
- 割り込みを自前で処理することか？  
- クロックサイクル単位での命令チューニングか？

この曖昧な表現の奥には、  
**ソフトウェアと物理の境界を巡る深い哲学的問い**がある。

本章では、アセンブリという語彙を通して、  
**「ハードウェアに近い」とはどういう状態なのか**を再定義していく。

---

## そもそも「近い」とは何か？

「近さ」は本質的に**抽象レイヤーの数**で定義される。

- C言語はアセンブリより高い  
- PythonはCよりもはるかに抽象的  
- OSのAPIはハードウェアの直接操作から隔てられている

つまり、**中間に介在する層が少ないほど、「近い」**とされる。

だがここで注意すべきは：

> **抽象を減らすこと＝制御可能性を高めることではない**

という事実である。

---

## 制御権と近接性：真の意味での「近さ」

真にハードウェアに近いとは、  
**「抽象を超えて、動作そのものを制御できる」**ことを意味する。

例：

- アセンブリで書かれた命令が、**そのまま電気信号に翻訳されること**  
- I/Oポートに書き込むことで、**物理デバイスが反応すること**  
- 割り込みベクタを操作して、**CPUの挙動を直に変えること**

ここで言う「近さ」は、**相対的な物理的距離**ではなく、  
**動作支配における直接性**だ。

---

## 抽象の重ねすぎがもたらす「遠さ」

たとえば、以下のコードを考えてみよう：

```python
print("Hello, world!")
```

この一行の背後には：

- インタプリタ  
- 標準ライブラリ  
- システムコール  
- OSのI/Oマネージャ  
- デバイスドライバ  
- PCIバス  
- メモリマップトI/O

といった、**数十層に及ぶ抽象**が存在する。

このコードが**どのタイミングでどのハードウェアを叩いているのか**は、  
書いた本人ですら知る由もない。

これこそが「遠さ」だ。

---

## アセンブリにおける「近さ」の感触

アセンブリを書くとき、  
設計者は次のような事実と対峙する：

- レジスタは存在し、今ここで使える  
- スタックは触れば変わるし、壊せる  
- 割り込みは止めれば止まるし、呼べば発火する  
- メモリはアドレスでしかなく、誤ればクラッシュする

これが「近さ」だ。

- **触れば壊れる**  
- **壊せば止まる**  
- **止まれば責任は設計者に帰す**

この感触が、  
高級言語では得られない「設計の実在性」である。

---

## ハードウェアに近づくと、設計者は何を得るか？

1. **動作に対する責任感**  
   - 成功も失敗も設計の結果と知る

2. **リソース感覚の獲得**  
   - メモリは無限ではなく、CPU時間は有限であることを肌で知る

3. **抽象化の根拠を学べる**  
   - OSや言語設計が、なぜそう構造化されたかの“理由”が分かる

4. **本質的な制御可能性の感覚**  
   - ソフトウェアが“可能性”ではなく、“物理”と向き合っている実感を得る

---

## 「近い」設計をすべきとき、すべきでないとき

**向いているケース：**

- 組み込み開発  
- デバイスドライバ設計  
- リアルタイムシステム（RTOS）  
- セキュリティ/バイナリ解析  
- 自作OS、ブートローダ

**向いていないケース：**

- 業務アプリケーション  
- Webフロントエンド  
- データベース設計  
- 高頻度のメンテナンスが必要な環境

「近い」設計は、高精度な理解と責任を要する。  
適切に使い分けることが、設計者の成熟を示す。

---

## 結語：距離とは、制御できる範囲のこと

ハードウェアに近いとは、  
物理的な「場所」ではなく、  
**設計者が責任を持って制御できる範囲のこと**である。

- それは知識と経験によってのみ近づける  
- それは責任を負う意志がなければ近づけない

抽象に逃げることで得られる速度は、  
ときに破綻と無理解を伴う。

だが近づくことで得られる遅さには、  
**設計の正確さと、動作の確かさ**がある。

> _"ハードウェアに近づくとは、世界に触れることだ。ソフトウェアの設計とは、本来そういうものだったのではないか？"_
セグメントレジスタの歴史的意味



> _"限界があったからこそ、構造が生まれた。そして、構造が思想を産んだ。"_  

現代のプログラマにとって、セグメントレジスタ（Segment Register）はもはや遠い存在かもしれない。  
だがかつて、それは**メモリ空間そのものを成り立たせていた中核の構造**だった。

- `CS`（Code Segment）  
- `DS`（Data Segment）  
- `SS`（Stack Segment）  
- `ES`, `FS`, `GS` …

この記号たちが担っていたのは、単なる実装上の制限回避ではない。  
それは、**メモリという広大な空間を人間の論理で統御しようとする試み**だった。

本章では、セグメントレジスタという過去の設計構造にこめられた思想を読み解き、  
それがなぜ重要であったのか、そしてなぜ廃れていったのかを再検証する。

---

## セグメントとは何か？

現代の64bitアーキテクチャでは、線形アドレス空間がほぼ常識となっている。  
しかし、x86の原初、8086プロセッサには、**メモリ空間の重大な制約**があった。

- 最大アドレス可能領域：1MB（20bit）  
- 1つのレジスタで扱えるアドレス幅：16bit（＝64KB）

この制約を突破するために生まれたのが、**セグメント方式**である。

セグメント方式の基本：

```
物理アドレス = セグメントレジスタ × 16 + オフセット
```

たとえば：

```assembly
MOV AX, [BX]    ; アクセス先 = DS:BX
```

ここで、`DS`（Data Segment）が選ばれる。  
つまり、プログラムは**常に「セグメント:オフセット」という二重構造**でアドレスを扱っていた。

---

## なぜセグメントという設計が必要だったのか？

当時、以下のような事情が存在していた：

- **16bitの限界**：アドレス空間が64KBまでしか表現できなかった  
- **コストの問題**：フル32bit（当時の観点では）アドレスバスは高価だった  
- **互換性問題**：8bit→16bitへの移行期だったため、段階的な設計が求められた

これらに応える形で：

- セグメントは**論理的なアドレス空間を「切り分け」**る手段となり  
- ハードウェア上の制約を**構造で吸収する**ことが試みられた

つまり、セグメント方式は、  
**設計が制限を肯定し、構造化へと転化した好例**なのである。

---

## セグメントレジスタの役割の分化

8086以降、x86は以下のようにセグメントレジスタを用途別に分化させた：

| レジスタ | 用途 |
|----------|------|
| CS       | 命令フェッチの基点 |
| DS       | データアクセスの基点 |
| SS       | スタック操作の基点 |
| ES       | 文字列処理・I/O向けの補助セグメント |
| FS/GS    | 拡張レジスタ（特にOSカーネル空間で利用） |

この分化によって、  
**各種メモリアクセスに意味的ラベルを付けることが可能になった。**

---

## セグメントは「意味論」だった

セグメントは、単にメモリを分割する構造ではなかった。  
それは、**コード／データ／スタックというプログラムの基本構造を、  
ハードウェア上に“物理的に反映させる”ための手段**だった。

現代では、これらの構造はすべて仮想アドレス空間で「抽象的」に表現されている。  
だがセグメント方式では、**それがリアルに空間として“割り当てられていた”**のだ。

この「物理的意味論」は、  
当時の設計に**極めて具体的な制御性と責任感**をもたらしていた。

---

## セグメントレジスタの衰退と仮想記憶の台頭

80386以降、x86アーキテクチャはフル32bitに進化し、  
ページングによる仮想記憶（Virtual Memory）が導入された。

この新しいパラダイムは：

- セグメントによる構造化を不要にし  
- 線形な巨大メモリ空間を前提にし  
- OS主導のアドレス変換と保護を可能にした

結果として：

- セグメントは形式上残されたが、**すべて同じ値が設定される「名義上の構造」**となり  
- `CS`, `DS`, `SS`のような分離も徐々に意味を失っていった

現代の64bitアーキテクチャでは、  
セグメントの影響はほぼ排除され、  
**FS/GSのような特殊用途を除き、ほぼ無効化されている。**

---

## では、なぜ今セグメントを学ぶのか？

それは、以下の設計思想を学ぶためだ。

1. **制限から生まれた構造**  
   - 限界を肯定し、構造として昇華する知恵

2. **空間と意味の結合**  
   - 構造と設計意図を物理レイヤに反映する技術

3. **抽象化以前の世界への洞察**  
   - 抽象が「何を隠し、何を前提にしているか」を知る

セグメントを学ぶことは、  
**抽象に頼りきった現代設計者が、その足元にある「制限」と「構造」の原点を見直すこと**に他ならない。

---

## 結語：消えた構造の声を聞く

セグメントレジスタは、今や使われない。  
だがその存在は、**設計者が「構造で限界を超えようとした」記憶**である。

- 抽象が生まれる前の、生々しい空間の感覚  
- 意味が設計の中に物理的に織り込まれていた時代  
- 誰もが設計と実装と物理を同時に扱っていた黎明期

それを知ることは、  
未来に向けた設計を、より深く、より確実に行うための基盤となる。

> _"消えた構造は、失われたのではない。私たちの中で、生きた構造の記憶として、今なお設計に影響を与え続けている。"_
とあるエンジニアのGW学習成果報告

０.はじめに
　　ネット上で報告することで、自身の学習のモチベーションを維持しようと試みる弱小エンジニアです。自己管理ができないんで、誰かに「いいね」してもらえると大変ありがたいですね。

１．GW中の学習計画
 ・基本情報のセキュリティ、ネットワーク分野の知識を詰め込む！
 　4日間（2025/5/3～5/6）に基本情報技術者試験のネットワーク、セキュリティ分野の学習を終わらせる。ネットワークで2日間、セキュリティを2日間で終わらせる。

２．結果
 ・基本情報の過去問道場を2周。
 　　1周目は用語を教本で一つ一つ確認しながら解いたので1問に15分かけることも…
   　2周目からはわかる用語や見たことあるってだけで抵抗感が薄れてきた。

３．感想
 ・1周目がきつい。
バイナリ互換性という幻想



> _"同じように動くことと、同じであることは、決して同義ではない。"_  

コンピュータシステムにおいて、  
**「互換性（Compatibility）」**は絶対的価値として語られる。

- バイナリ互換  
- ソース互換  
- API互換  
- ABI互換

中でも、**バイナリ互換性**は、  
「既存の実行ファイルが、そのまま動く」という  
魔法のような約束として尊ばれてきた。

だがアセンブリの視点でこの言葉を見つめ直せば、  
**その内実がいかに脆く、不確実で、幻想に近いものか**が見えてくる。

---

## バイナリ互換性とは何か？

バイナリ互換性（Binary Compatibility）とは：

> 「同じ実行バイナリ（.exe, .elfなど）が、異なる環境でも同じように動作すること」

を意味する。

例：

- Windows XP時代のアプリが、Windows 11でも動く  
- x86でビルドされたアプリが、別のx86マシンでも動く

これは、**ユーザー体験の継続性**を支える重要な設計要件である。

---

## なぜ互換性は幻想なのか？

バイナリ互換性は、「動く」ことだけに焦点が当たっている。  
だがその裏では、**綱渡りのような維持努力**が続けられている。

### 1. OSレベルの偽装とレイヤー補正

- WindowsはAPIラッパーを通じて旧バージョンをエミュレートしている  
- Linuxは`ld-linux`などのローダー互換性を調整し続けている

### 2. ハードウェアのエミュレーション

- x86は未だに8086の命令セットを保持している  
- ARMではAArch32/AArch64のデュアル命令セットが併存

これらの努力はすべて、  
**「過去を維持するための未来の犠牲」**によって成立している。

---

## アセンブリ視点で見ると何が見えるか？

アセンブリから見た互換性の世界には、**無数の分断と再構築の痕跡**がある。

- 同じMOV命令でも、64bitと32bitでは内部動作が異なる  
- セグメントレジスタは、あるアーキテクチャでは意味を失っている  
- スタック配置やABIの違いで、同じ命令でも異なる結果を返す

つまり、  
**見かけ上は「動いている」ように見えるが、  
その実体はまるで別物**なのだ。

---

## バイナリ互換性がもたらす設計上の歪み

バイナリ互換性を保つことには、代償が伴う。

- **冗長な命令セットの維持**  
- **レガシーAPIのサポート負債**  
- **セキュリティホールの温存（例：Win32の古典的脆弱性）**  
- **最適化阻害（古い形式との整合性を保つため）**

設計者が新しい技術を導入しようとするたび、  
**過去との互換性が足枷になる**。

それは、  
「新しい設計を殺すのは、常に古い設計だ」  
というジレンマの体現である。

---

## 完全な互換性など存在しない

たとえば：

- バイナリが動いていても、浮動小数点の丸め規則が変われば結果は変わる  
- キャッシュラインサイズの違いで、性能が激変する  
- パイプライン設計の違いで、タイミングが崩壊する（リアルタイム性が死ぬ）

このように、  
**バイナリが“動く”という事実は、何一つ保証しない。**

そこにあるのは、**限りない偶然と設計の残滓**である。

---

## 「移植性」と「互換性」の混同

「互換性」という言葉は、しばしば「移植性」と混同される。

- 移植性：ソースコードや設計が、異なる環境でも容易に再利用できる  
- 互換性：同一バイナリがそのまま動作する

両者は**似て非なる概念**だ。

アセンブリにおいては：

- 移植性は皆無（命令セットに強く依存）  
- 互換性はハードウェアとOSの執念によって成り立っている

この違いを誤解すると、  
設計が**思考停止の泥沼**に沈む。

---

## 真に設計者が目指すべきもの

設計者が重視すべきは、  
**「透明性」と「制御性」**である。

- 今の環境で、なぜこれが動いているのか  
- どの層に依存しているのか  
- 将来、何を犠牲にしてでも維持されるのか

これを理解した上で、  
**「偶然の上に設計を立てない」**こと。

バイナリ互換性は、  
**今は使えるが、永遠に使えるとは限らない「幻の橋」**に過ぎない。

---

## 結語：幻想を設計に組み込んではならない

バイナリ互換性は、便利だ。  
だがそれは設計者のためにあるのではない。  
それは**「市場のための互換性」であり、「設計のための正しさ」ではない。**

設計者は幻想に惑わされてはならない。  
本質的な設計とは、

- 構造の可視化  
- 層の分離  
- 依存の意図的設計  

によってこそ成立する。

> _"互換性を信じるな。それが続く限りにおいて、感謝せよ。そして、それが壊れた時に、すぐ立て直せる構造を設計せよ。"_
手続き型から命令列へ：パラダイムの断絶



> _"意図を手続きに落とす者、機械を命令で支配する者。それは似て非なる生き物だ。"_  

プログラミングの世界には、  
数々のパラダイム（思考枠組み）が存在する。

- 手続き型（Procedural）  
- オブジェクト指向（Object-Oriented）  
- 関数型（Functional）  
- 宣言型（Declarative）

だがアセンブリの世界においては、  
**「手続き」すら存在しない。**

そこにあるのはただ、**命令列（Instruction Stream）**という生々しい連続体だけだ。

この章では、  
手続き型プログラミングと命令列設計の間に横たわる、  
**パラダイムの断絶**を掘り下げる。

---

## 手続き型プログラミングとは何か？

手続き型とは：

- 状態を持つ世界を前提とし  
- 命令の「手順」を積み重ねて  
- 世界を意図的に変化させる

プログラミングパラダイムである。

特徴：

- 関数やプロシージャにまとめる  
- 変数と代入を駆使する  
- 流れ（Flow）を設計する

代表言語：C、Pascal、BASICなど

この考え方は、  
**人間の思考プロセス（手順の列挙）に自然に対応している。**

---

## 命令列（Instruction Stream）とは何か？

一方、アセンブリの世界は異なる。

そこでは：

- 関数も手続きも存在しない  
- ただ順に並べられた命令列だけが存在する  
- 条件付きジャンプとラベルが、かろうじて流れを制御する

特徴：

- すべてが「次に何をするか」を明示的に記述する  
- 制御構造は人工的に構成するしかない（ループ、条件分岐など）  
- 「抽象化」ではなく「列挙と制御」によって動作を定義する

つまり、  
**「世界に対して命令を積み重ねる」**のではない。  
**「世界の上に命令列を這わせる」**のである。

---

## 手続き型と命令列：どこが断絶しているのか？

| 項目 | 手続き型 | 命令列 |
|:-----|:--------|:------|
| 単位 | 関数・プロシージャ | 命令単位 |
| 流れの設計 | 制御構造（if/for/while）で表現 | 条件ジャンプとラベルで手動設計 |
| 可読性重視度 | 高い（意図が構造化される） | 極めて低い（意図は隠れている） |
| エラー許容度 | 抽象化による緩和あり | すべて設計者の責任 |

手続き型は、  
**「人間にとって自然な世界の再構築」**を目指す。  
命令列は、  
**「機械が理解できる最低限の流れの刻印」**を目指す。

この断絶こそが、  
アセンブリの設計における最大の特徴である。

---

## 命令列設計の難しさ

命令列設計の難しさは、  
**「未来が見えない中で局所最適を積み重ねる」**ことにある。

たとえば：

- あるレジスタが今必要か、あとで必要か、常に意識する  
- ジャンプ命令がパイプラインに与える影響を予測する  
- 分岐先と分岐元の一貫性を保証する

これらすべてを、  
**関数やスコープという緩衝材なしに**設計しなければならない。

それは、  
**裸で世界と向き合う設計行為**だ。

---

## なぜこの断絶を越える必要があるのか？

高級言語で設計するだけでは見えないものが、  
命令列設計には明確に現れる。

- キャッシュラインの汚染  
- 分岐予測の失敗  
- レジスタリソースの飢餓  
- スタックフレームの膨張

これらの**低レイヤ問題**は、  
命令列を理解しない限り、  
**根本的な解決はできない。**

設計者が命令列を読むことは、  
**「抽象の下に流れる現実の川を知る」**ことに等しい。

---

## 手続き型→命令列：精神的な断絶を越えるために

手続き型→命令列へと意識をシフトするには、次の覚悟が要る。

- **抽象を一度手放すこと**  
- **流れを明示的に設計すること**  
- **リソースの物理的制約を受け入れること**  
- **エラーも予測不能も設計の一部と認めること**

そして何より、  
**「設計とは、制御することだ」**  
という原始的な感覚を取り戻すこと。

これが、  
命令列設計へ飛び込むための精神的準備だ。

---

## 結語：命令列に降り立つということ

命令列は無機質だ。  
そこには、クラスも、オブジェクトも、関数もない。

だがその無機質の中に、  
設計の本質が剥き出しで存在する。

- 一手ごとにリスクを背負い  
- 一命令ごとに世界を変える

それが、命令列設計という行為だ。

> _"抽象の殻を破り、裸の命令列の上に立つとき、設計者は初めて、世界を自らの手で再設計する力を得る。"_
レジスタアロケーションという無音の戦略



> _"最も静かな部分にこそ、最も激しい設計が宿る。"_  

プログラムが動作するとき、  
私たちの目に見えるのは関数、クラス、モジュール、アーキテクチャ。  

だがそのはるか下層で、  
**見えない小さな資源管理戦争**が繰り広げられている。

それが、  
**レジスタアロケーション（Register Allocation）**という無音の戦略である。

この章では、アセンブリ視点から、  
**レジスタアロケーションという設計の深層構造**を掘り下げる。

---

## レジスタとは何か？

レジスタとは、  
**CPU内部にある超高速な記憶領域**である。

特徴：

- アクセス速度：ほぼゼロクロック（メモリアクセスの数百分の一）  
- サイズ制限：極めて少ない（x86では一般用途で10数本程度）  
- 直接演算可能：メモリとは異なり、即座に演算対象にできる

つまり、レジスタは、  
**最速であり、最も希少な資源**だ。

---

## レジスタアロケーションとは何か？

レジスタアロケーションとは：

- プログラム中の一時変数やデータを  
- 限られたレジスタにどのように割り当てるかを決める

設計行為である。

簡単に言えば、  
**「誰をどの座席に座らせるか」を決める**仕事だ。

ただし座席は限られている。  
争奪戦も発生する。  
一度ミスれば、プログラムは壊れる。

だからこそ、  
**静かでありながら、最も熾烈な設計領域**となる。

---

## なぜレジスタアロケーションが重要なのか？

理由は単純だ。

- レジスタ利用率が高ければ、高速なプログラムになる  
- レジスタの不足をメモリアクセスで補うと、性能が急落する（レジスタスピル）

最悪の場合：

- L1キャッシュミス  
- メモリアクセス待機によるパイプラインストール  
- 分岐予測失敗との複合悪化

が重なり、  
**設計全体が破綻する。**

つまり、レジスタアロケーションとは、  
**プログラム全体の呼吸リズムを決定する設計**なのだ。

---

## レジスタアロケーションの基本戦略

1. **リソース優先順位付け**  
   - よく使われる変数を優先してレジスタに保持

2. **ライブレンジ短縮**  
   - 変数が使われる範囲（ライブレンジ）をできるだけ短くする

3. **スピル最小化**  
   - どうしてもレジスタが足りない場合のみ、メモリ（スタック）へ逃がす

4. **生存区間解析（Liveness Analysis）**  
   - 変数がどこからどこまで生きているかを精密に把握する

これらを組み合わせて、  
**「限られたリソースを最大効率で回す」**設計が求められる。

---

## グラフ彩色問題としてのレジスタアロケーション

コンパイラ理論では、  
レジスタアロケーションは**グラフ彩色問題**に還元される。

- 頂点＝変数  
- 辺＝同時に生きる（コンフリクトする）関係  
- 色＝レジスタ番号

問題設定：

> 隣接する頂点が同じ色（レジスタ）にならないように、最小の色数でグラフを彩色せよ。

この問題はNP困難であり、  
コンパイラはこれに対して：

- ヒューリスティックアルゴリズム  
- グラフ簡略化  
- スピル挿入と再試行

といった工夫を重ねる。

つまり、  
**レジスタアロケーションとは、コンパイラ設計者による静かな知能戦争**なのだ。

---

## 手書きアセンブリでのレジスタ設計

コンパイラに頼らず、  
手書きアセンブリを書く場合、  
設計者自身がレジスタアロケーションを担うことになる。

設計者は：

- 演算結果の保持場所  
- 途中変数の一時退避  
- 呼び出し規約による保存義務

をすべて意識して設計する。

手書きアセンブリにおいて、  
レジスタ設計の美しさこそが、  
**そのプログラムの寿命と信頼性を決定する。**

---

## レジスタアロケーションにおける哲学的選択

設計者は常に問われる。

- **局所最適化に走るか？**
  - 小さなブロック内だけでレジスタ最適化を図る
- **グローバル最適化を志向するか？**
  - 関数全体、モジュール全体でのリソース最適化を狙う

局所最適化は簡単だ。即効性もある。  
だがグローバル最適化は、設計者に**より高い抽象化力と予測力**を要求する。

どちらを選ぶかは、  
**設計者の思想そのもの**を映す。

---

## 結語：静かな部分にこそ、設計者の力は現れる

レジスタアロケーションとは、  
目立たない。

関数名にも現れない。  
ドキュメントにも記されない。  
デモにも映らない。

だが、  
プログラムの**性能・安定性・美しさ**は、  
この無音の領域に支えられている。

そして、  
静かな設計こそが、  
最も深い設計力を試す。

> _"レジスタを制する者は、設計を制する。最も静かな場所にこそ、最も深い戦略が宿る。"_
atcoder緑(記録)

**Atcoderで緑になりました！**



*記録用の記事です
スクショしか貼ってないです
ABC404(2025-05-03)
https://atcoder.jp/contests/abc404
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/784e520a-0603-40bd-a19b-916879ae8566.png)
初参加(ABC354 2024-05-18)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/c0e52e32-af7d-47b9-a4d3-ae05e183037b.png)

2025-05-12時点の記録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/49d053aa-5045-4d36-a281-282530f52da9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/1eefa77c-118c-4b24-baf9-93716705cbef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/3820db6d-2a64-479a-a442-50b8260929b8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/a3a5bef0-e27e-4759-a82b-4b27cb828fb7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/e947713e-e9a0-4cbe-b737-4fc18d343ebf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/1d93ab17-52b2-4d68-bb2e-50ca63b78fc4.png)

ABC361~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/e48a628d-8bcc-418f-8a5e-753959044b21.png)

~ABC313
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/958779a3-df27-4260-bdaa-cd28e83ffb8d.png)

~ABC266
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/d8d6295f-0031-4d60-985b-f1b1111aa34a.png)

~ABC218
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/a3000cfb-262c-4de7-8d6a-6b4a555cbcd2.png)

~ABC187
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085781/35e33b6e-4e32-4bec-8660-7395f93dc764.png)
やったこと
EDPC Fまで
茶diff、c,d問題埋め
adtなど

やること
EDPC(現在Fまで)
典型90?
緑diff埋め(バチャたててみたい)

年内に水目指したいとおもいます！
最適化しないという最適化



> _"速さを求めすぎた者は、制御を失う。"_  

プログラミングにおいて、「最適化（Optimization）」は神話のように語られる。  
より速く、より小さく、より効率的に――  
あらゆる設計者がこの呪文に魅了されてきた。

だがアセンブリ、そして低レベル設計の世界では、  
ときに**「最適化しないこと」こそが最良の最適化**となる。

本章では、**意図的非最適化**という逆説的な設計思想を、  
アセンブリ視点から掘り下げる。

---

## 最適化とは何を意味するか？

最適化とは：

- リソース（時間・空間）の消費を減らすために  
- 動作をより効率的に書き換えること

を指す。

だが重要なのは、  
**「何に対して最適化するのか」**という問いだ。

- 実行速度？  
- メモリ使用量？  
- 消費電力？  
- 設計の単純性？  
- 保守性？

最適化は、  
**常に何かを犠牲にして、何かを得る行為**である。

---

## なぜ最適化は危険なのか？

過剰な最適化は、しばしば次のような副作用をもたらす。

- **可読性の低下**  
- **保守性の低下**  
- **デバッグ困難化**  
- **アーキテクチャ依存性の増大**  
- **将来的な最適化可能性の破壊**

つまり、  
最適化とは、単なる技術的操作ではない。  
**「未来に対する設計的債務をどこまで積み上げるか」**という選択なのだ。

---

## アセンブリにおける「最適化しない」という選択

アセンブリでは、ときに：

- 速度を犠牲にしても  
- サイズを犠牲にしても  
- 美しい構造を維持する

という選択がなされる。

理由は明確だ。

- **意図が明示的になる**  
- **バグ検出が容易になる**  
- **移植性が高まる**  
- **未来の最適化余地が残される**

この「意図を守る」という行為が、  
長期的には**最高の最適化**へとつながる。

---

## 例：インライン展開しない勇気

たとえば、関数呼び出しをインライン展開（展開＝関数コードを直接埋め込む）すると、  
実行速度は向上するかもしれない。

だが、

- コードサイズが膨張する  
- 命令キャッシュ効率が低下する  
- デバッグが困難になる

といった副作用がある。

**「あえて関数呼び出しを保つ」**  
これは、最適化を一時的に犠牲にする代わりに、  
**設計の持続性を守る行為**なのだ。

---

## 例：ループアンローリングしない選択

ループアンローリング（展開）も同様だ。

```assembly
; 展開なし
LOOP_START:
  MOV EAX, [EBX]
  ADD EBX, 4
  DEC ECX
  JNZ LOOP_START
```

```assembly
; 展開あり
MOV EAX, [EBX]
ADD EBX, 4
MOV EAX, [EBX]
ADD EBX, 4
...
```

展開すれば分岐回数が減り、速度は上がる。  
だが：

- コードのメンテナンス性は落ち  
- 容易にバグが入り込み  
- キャッシュ圧迫も起きやすくなる

こうした事情から、  
**「あえてループを保つ」**という設計判断が選ばれることもある。

---

## 最適化する前に問うべき3つのこと

1. **本当にここがボトルネックなのか？**  
2. **この最適化は、将来の変更をどれだけ困難にするか？**  
3. **この最適化は、設計意図を濁らせないか？**

これらすべてに明確な答えが出たとき、  
初めて**「本当に必要な最適化」**だけが許される。

それ以外は、  
**最適化しないという最適化**が推奨される。

---

## 最適化は「設計の終着点」ではなく「設計の変曲点」である

最適化とは、  
設計の完成ではない。

むしろ、  
設計の意図と実装の現実がぶつかり合う場所であり、  
**設計者が最も深く「何を守り、何を犠牲にするか」を問われる場**である。

- 最適化することで設計意図が失われるなら、それは本末転倒  
- 最適化することで設計が壊れるなら、それは設計の敗北

---

## 結語：最適化とは、設計思想を問い直す行為である

アセンブリにおける最適化とは、  
単なる速度競争ではない。

それは、  
**設計意図、可読性、保守性、未来への耐久性**  
これらすべてを総合的に考えた上で、

- どこを守り  
- どこを削り  
- どこを解放するか

を静かに選び取る行為である。

そしてときに、  
**「最適化しない」という選択こそが、最も洗練された最適化となる。**

> _"最適化とは、削ぎ落とすことではない。守るべきものを見極め、犠牲を選び抜く、設計者の静かな意志表明である。"_
インラインアセンブリ：高級言語との対話



> _"境界を越えて対話することで、世界は広がる。"_  

高級言語。  
それは、人間に優しい抽象によって設計されている。  

アセンブリ。  
それは、機械に忠実な透明性によって設計されている。  

本来、これら二つは相容れない世界だった。  
だが、**インラインアセンブリ（Inline Assembly）**という技法は、  
この二つの異なる世界を**静かに橋渡し**する。

この章では、インラインアセンブリの存在が、  
**設計にどのような新たな対話をもたらすか**を掘り下げる。

---

## インラインアセンブリとは何か？

インラインアセンブリとは：

- 高級言語（C, C++, Rustなど）の中に  
- 生のアセンブリコードを直接埋め込み  
- コンパイラを通じてそのまま機械語に変換させる

技法である。

イメージとしては：

```c
int add(int a, int b) {
    int result;
    __asm__ ("addl %%ebx, %%eax" : "=a" (result) : "a" (a), "b" (b));
    return result;
}
```

この数行で、  
**高級言語の世界と機械語の世界が直接繋がる。**

---

## なぜインラインアセンブリが必要なのか？

主な理由は三つある。

### 1. 極限までの最適化

- コンパイラが生成できないレベルの最適化（サイクル単位チューニング）
- 特定のハードウェア命令（例えばSIMD, 暗号命令）への直接アクセス

### 2. ハードウェア資源への直接制御

- 特権命令  
- I/Oポート操作  
- CPUフラグ制御

### 3. 実験と可搬性検証

- 新しい命令セットの試験  
- クロスプラットフォームな低レベルライブラリの設計

つまり、**人間の意図がコンパイラの推論を超える場面**で、  
インラインアセンブリは必要になる。

---

## インラインアセンブリは「対話」である

インラインアセンブリは、  
高級言語とアセンブリの**単なる併存**ではない。

それは、**意図の対話**である。

- 高級言語：抽象化された構造を設計する  
- アセンブリ：構造の内部に具体的な最適性を注入する

この二重構造によって、  
プログラムは「設計」と「実装」の両極を**同時に扱う**ことが可能になる。

---

## インラインアセンブリの形式（GCCスタイル例）

GCCでは次のような基本構文を取る：

```c
__asm__ ( assembler template 
         : output operands 
         : input operands 
         : clobbered registers );
```

各フィールドの意味：

- **assembler template**：アセンブリ命令（文字列）
- **output operands**：アセンブリ命令によって出力される変数の指定
- **input operands**：アセンブリ命令に渡す入力変数の指定
- **clobbered registers**：破壊されるレジスタの宣言

これは、単なる生コードの埋め込みではなく、  
**「文脈に沿った安全な埋め込み」**を意図して設計されている。

---

## インラインアセンブリが設計にもたらす緊張感

インラインアセンブリを使用するということは、  
高級言語の「保証された安全性」から一部離脱することを意味する。

- 型安全性の一部放棄  
- 最適化パスの手動設計  
- プラットフォーム依存性の導入

これは、設計者に次の覚悟を要求する：

> 「この小さな無保証領域を、自分の設計責任で統御する」

インラインアセンブリは、  
**設計者に強い自覚と技術的洞察を求める「鋭利な道具」**なのである。

---

## インラインアセンブリとクロスプラットフォーム開発

インラインアセンブリはしばしば、  
移植性に対するリスクを伴う。

- x86用に書いたインラインアセンブリは、ARM上では使えない  
- CPUごとに命令セットも、レジスタ数も異なる

これを回避するための戦略：

- アセンブリ部分を明確に抽象化する（例えばアーキテクチャ別ヘッダを用意）  
- 必要最小限のアセンブリに留める  
- コンパイラベンダの組込みインライン命令を活用する（例：GCCの`__builtin_popcount`など）

つまり、**「局所的にロックインするが、グローバルには抽象を保つ」**  
という高度な設計バランスが求められる。

---

## インラインアセンブリを書くとは何を意味するか？

それは、設計者が：

- 抽象と実装の境界を意図的に開き  
- 機械と直接会話し  
- その上で、再び抽象へと戻る

という、**極めて高度な往復運動**を遂行することを意味する。

インラインアセンブリは、  
設計者にこう問いかける。

> 「あなたは本当に、この設計空間を理解しているか？」

---

## 結語：対話とは、二つの世界を尊重すること

インラインアセンブリは、  
単なる「トリック」や「裏技」ではない。

それは、

- 人間的な抽象と思考と  
- 機械的な効率と正確性を

**同時に尊重し、交差させるための対話の技術**である。

設計者がこの対話を受け入れるとき、  
プログラムはより柔軟に、より力強く、より深く世界に根ざすことができる。

> _"インラインアセンブリとは、抽象と具体の間にかけられた一本の細い橋である。渡る覚悟を持った者だけが、その向こう側を設計できる。"_
呼び出し規約ABI比較：System V vs Windows ABI



> _"違いを知ることは、設計の自由を知ることだ。"_  

関数呼び出し規約（Calling Convention）は、単なる実装細部ではない。  
それは、**異なる設計文化、異なる歴史、異なる哲学の表れ**である。

本章では、  
現代最も広く使われる二つのABI――  
**System V ABI（UNIX系）**と**Windows ABI**を比較し、  
**その設計思想と本質的な違い**を深掘りしていく。

---

## まず前提として：ABIとは何か？

ABI（Application Binary Interface）とは：

- 関数の呼び出し方法（引数の受け渡し、戻り値の扱い）  
- データ型のサイズと配置（アライメント規則）  
- バイナリフォーマット（例：ELF, PE）

などを包括的に定義する、**低レベル設計の国際法**である。

ABIに従うことで：

- 異なるコンパイラでビルドされたモジュール同士  
- 異なる言語で書かれたプログラム同士

が、**バイナリレベルで相互運用可能**となる。

---

## System V ABI（Unix/Linux系）とは

System V ABIは、主に：

- Linux  
- FreeBSD  
- macOS  
- その他UNIX互換OS

で使用される、**UNIX文化圏の標準ABI**である。

特徴：

- 引数は**最初の6個までレジスタ渡し**（x86-64では`RDI, RSI, RDX, RCX, R8, R9`）  
- それ以降はスタック上に積む  
- スタックは**16バイト境界にアライメント**される  
- 呼び出し側がレジスタ保存を責任持つ（Caller-save中心）

哲学的には、  
**「高速性」と「呼び出しコスト削減」**を重視している。

---

## Windows ABI（Microsoft x64 calling convention）とは

Windows ABI（特に64bit版）は、Microsoftが定めた標準であり：

- Windows NT系（Windows 10/11、Windows Server）  
- それに準拠する全アプリケーション/ドライバ

で使用される。

特徴：

- 引数は**最初の4個までレジスタ渡し**（`RCX, RDX, R8, R9`）  
- それ以降はスタックに置く  
- **Shadow Space（32バイト）**を事前にスタック上に確保する  
- 呼び出し先がShadow Spaceに必ずアクセスできることを保証  
- Callee-save（呼び出される側保存）のレジスタ群が多い（`RBX, RBP, RDI, RSI, R12〜R15`）

哲学的には、  
**「堅牢性」と「拡張性」**を強く意識している。

---

## 引数渡しの違い

| 項目 | System V ABI | Windows ABI |
|:----|:-------------|:------------|
| レジスタ数 | 最大6個 | 最大4個 |
| レジスタ順序 | RDI, RSI, RDX, RCX, R8, R9 | RCX, RDX, R8, R9 |
| 追加引数の渡し方 | スタック（右から左） | スタック（左から右） |
| 特記事項 | レジスタ優先・高性能志向 | Shadow Spaceによる堅牢設計 |

System Vは**高速性と柔軟性**、  
Windows ABIは**予測性と安全性**を設計目標にしていることが分かる。

---

## スタックアライメントの違い

System Vでは：

- 関数呼び出し時に**16バイト境界にスタックをアライン**しなければならない
- SIMD命令（例：SSE, AVX）を考慮した設計

Windows ABIでは：

- 関数エントリ時に、**Shadow Space（32バイト）**を積んだうえで16バイトアライメントを保証する
- 固定レイアウトによる堅牢化を志向

この違いもまた、  
**「設計自由度を重視するか」「堅牢性を重視するか」**という設計思想の分岐を示している。

---

## レジスタ保存（Caller-save vs Callee-save）

System Vは：

- 呼び出し側（Caller）が重要なレジスタを保存する文化  
- 呼び出される関数は、破壊的にレジスタを使用できる  
- 小規模・高速な関数呼び出しを最適化

Windows ABIは：

- 呼び出される側（Callee）が広範囲にレジスタ保存責任を負う  
- 呼び出し元にやさしい（レジスタ破壊リスク低減）  
- 安定性とモジュール間互換性を強く意識

ここでも、  
**「速さを取るか、堅牢さを取るか」**という対照が際立つ。

---

## 呼び出し規約選択がもたらす設計への影響

呼び出し規約の違いは：

- 最適化戦略  
- クロスプラットフォーム開発難易度  
- バイナリ互換性の取り扱い  
- システムコールインターフェース設計

などに直結する。

設計者は、  
**単なる性能指標だけでなく、長期的な保守性や可搬性も視野に入れた選択**を迫られる。

---

## 結語：呼び出し規約は、文化の結晶である

System VとWindows ABI。  
それぞれが歩んだ道は異なる。  
だがどちらも、**その文化圏における設計哲学の結晶**である。

- どちらが正しいわけでも、優れているわけでもない  
- 選択は、設計者の目的と世界観に依存する

> _"設計とは、選択の連続であり、文化の反映である。呼び出し規約は、その沈黙の文化をコードに刻む、静かな契約である。"_
VS Code Server for WSL closed unexpectedlyが起こったときの対処方法


# はじめに

VS CodeでWSL（Windows Subsystem for Linux）環境のプロジェクトを開こうとした際、「VS Code Server for WSL closed unexpectedly」というエラーが発生し、リモート接続できなくなることがあります。このエラーはWSLの設定やVS Code Serverの不整合など、さまざまな原因で発生します。本記事では、代表的な解決策をわかりやすくまとめます。

---

# 1. WSL側のVS Code Serverバイナリを削除する

一番多い原因は、WSL内のVS Code Serverバイナリが壊れている、または不整合が発生しているケースです。  
この場合、WSL側でVS Code Serverの`bin`ディレクトリを削除することで自動的に再インストールされ、解決することが多いです。

```bash
rm -rf ~/.vscode-server/bin/
```

VS Codeを一度終了してから上記コマンドを実行し、再度VS CodeでRemote WSL接続を試してください。  
`bin/`以下が空ファイルになっている場合なども、この方法で解決します。

---

# 2. WSLのパッケージを最新化する

必要なパッケージが不足していたり、証明書関連で問題が発生している場合もあります。  
WSLのターミナルで以下を実行し、`wget`と`ca-certificates`をインストール・更新しましょう。

```bash
sudo apt-get update && sudo apt-get install wget ca-certificates
```


---

# 3. 既定のWSLディストリビューションの確認・設定

複数のWSLディストリビューションを利用している場合、既定のディストリビューションと実際に起動しているものが食い違っているとエラーが出ることがあります。  
PowerShellで以下を実行し、既定のディストリビューションを確認・設定しましょう。

```powershell
wslconfig /l
wslconfig /setdefault 
```
例:  
```powershell
wslconfig /setdefault Ubuntu-20.04
```


---

## 4. WSLの再起動

WSL自体の不調が原因の場合もあるため、WSLを再起動してみましょう。

```powershell
wsl --shutdown
```
その後、再度WSLを起動してVS Codeから接続します。

---

## 5. 公式ドキュメントのトラブルシューティングを参照

VS Code公式のWSLトラブルシューティングガイドも参考になります。  
ログの確認や詳細なデバッグ方法も掲載されています。

- [Remote Development Tips and Tricks - WSL](https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips)

---

## 6. その他のチェックポイント

- VS Code本体やRemote - WSL拡張機能が最新か確認
- WSLのバージョン（できればWSL2推奨）やWindowsのアップデート状況を確認
- プロキシやウイルス対策ソフトの影響がないか確認

---

## まとめ

「VS Code Server for WSL closed unexpectedly」は、**WSL側のVS Code Serverバイナリ削除→自動再インストール**で直るケースが多いですが、パッケージ不足やディストリ設定の不一致など他の要因も考えられます。  
本記事の手順を順番に試し、解決しない場合は公式ドキュメントやWSLのログを確認しましょう。**困ったときはまず「binディレクトリ削除」→「パッケージ更新」→「ディストリ設定」→「WSL再起動」の順で試してみてください！**
関数呼び出し規約：設計者間の静かな契約



> _"契約とは、自由を制限することで、秩序を得る行為である。"_  

コンピュータプログラムにおいて、関数とは小さな宇宙だ。  
だが、その宇宙同士が出会い、交わり、協調するためには、  
**「秩序」が必要となる。**

この秩序を支えるもの。  
それが、**関数呼び出し規約（Calling Convention）**である。

この章では、呼び出し規約という静かな契約が、  
どのように設計者間の信頼と相互作用を支えているかを探る。

---

## 関数呼び出し規約とは何か？

関数呼び出し規約とは、  
**「関数間でデータをどのように受け渡し、制御をどのように戻すかを定めた取り決め」**である。

具体的には：

- 引数をどこに置くか（レジスタか、スタックか）  
- 戻り値をどこに格納するか  
- どのレジスタを関数間で保存するか（callee-save / caller-save）  
- スタックポインタの管理ルール

この取り決めがなければ、  
関数同士は互いを信頼できず、協調することはできない。

---

## なぜ呼び出し規約が必要なのか？

理由は明確だ。

- 関数同士は**別々にコンパイル**されることがある  
- ライブラリは**外部からリンク**される  
- コンパイラは**コード生成を最適化**する必要がある

このとき、呼び出し規約という**事前の約束**がなければ、  
- 引数をどこで読むか分からない  
- 戻り先を間違える  
- レジスタ内容が破壊される  

といった、**破滅的な結果**を招く。

---

## 呼び出し規約の具体例（x86）

例えば、x86の代表的な規約には：

- **cdecl**  
  - 引数は右から左にスタックに積む  
  - 呼び出し側がスタックを片付ける
- **stdcall**  
  - 引数は右から左にスタックに積む  
  - 呼び出される関数側がスタックを片付ける
- **fastcall**  
  - 最初の数個の引数をレジスタ（通常ECXとEDX）に渡す

どの規約を選ぶかで、  
- 関数の呼び出しコスト  
- 最適化しやすさ  
- インターフェースの柔軟性  

が大きく変わる。

---

## 呼び出し規約の設計思想：自由か、制約か

呼び出し規約設計において、常に問われるのは：

- レジスタをどこまで使う自由を許すか  
- スタックアクセスをどこまで規制するか  
- 呼び出し側と呼び出される側、どちらに責任を負わせるか

例えば：

- **callee-save重視**（呼び出された側が保存）  
  → 関数内部の自由度は高いが、負荷は関数側にかかる
- **caller-save重視**（呼び出す側が保存）  
  → 呼び出しコスト増大だが、関数自体はシンプル

このトレードオフは、  
**「局所最適」か「グローバル最適」か**という、  
設計哲学の選択でもある。

---

## 呼び出し規約の「見えない力」

普段、プログラマが意識しない場所で、  
呼び出し規約は静かに機能している。

- リンクされたライブラリ同士が、互いを理解できるのはなぜか  
- OSカーネルとユーザプログラムが安全に制御を渡し合えるのはなぜか  
- C、C++、Rust、Goなど異なる言語間で相互運用できるのはなぜか

そのすべては、  
**関数呼び出し規約という、静かな契約が存在するから**である。

---

## 呼び出し規約を破ったとき、何が起きるか？

もし、呼び出し規約を無視して関数を呼び出すと：

- 引数がずれる  
- スタックポインタが壊れる  
- 戻り先アドレスが破壊される  
- プログラムが即座にクラッシュする

これは単なるバグではない。  
**契約違反による、構造の崩壊**である。

---

## ABI（Application Binary Interface）と呼び出し規約

呼び出し規約は、より広い意味でのABI（アプリケーションバイナリインターフェース）の一部である。

ABIは：

- データ型のサイズと配置  
- 呼び出し規約  
- バイナリフォーマット

を定め、  
**異なるコンパイラ、異なる言語、異なるプログラム間の共存を可能にする。**

つまり、ABI＝**「設計者たちの国際法」**のような存在である。

---

## 呼び出し規約を理解するとは何を意味するか？

呼び出し規約を理解するとは：

- コードの深層構造を読む力を得ること  
- バイナリレベルでプログラムを解析する力を得ること  
- 自ら独自インターフェースを設計できる力を得ること

単なる関数の呼び出し手続きではない。  
それは、**設計者同士が無言で握手を交わすための、最も基本的な「作法」**である。

---

## 結語：契約は、設計者たちの沈黙の言葉である

関数呼び出し規約は、見えない。  
だがそれは確実に存在し、すべてを支えている。

- 一貫した設計  
- 相互運用性  
- 信頼できる制御フロー

これらすべては、  
**静かに交わされた契約の上に成り立っている。**

> _"設計とは、沈黙のうちに交わされた無数の契約でできている。呼び出し規約は、その最も静かで、最も強固な契約である。"_
アセンブリは「最も透明なコード」である



> _"隠すものがないとき、すべての責任は設計者に帰する。"_  

現代のプログラミング言語は、  
高い抽象化、高機能な標準ライブラリ、洗練された開発環境に支えられている。

だがその裏で、  
**「何が起きているか」**はますます不透明になっている。

アセンブリは違う。  
アセンブリは、**すべてを暴き出す。**

この章では、アセンブリという存在が、  
なぜ**「最も透明なコード」**と呼ばれるにふさわしいかを探る。

---

## 透明性とは何か？

プログラムにおける透明性とは、  
**「コードが実行される動作が、そのまま理解できること」**である。

- メモリに何を置くか  
- レジスタに何を載せるか  
- どの命令を順に実行するか  
- どこで分岐するか

これらすべてが、  
**設計者に明示的に見えている状態**を指す。

---

## アセンブリはなぜ透明なのか？

理由は単純だ。

- コンパイラの最適化が存在しない（または極小）  
- ランタイムによる動的な介入が存在しない  
- 自動メモリ管理やガベージコレクションが存在しない  
- コード＝機械命令である

つまり、  
**「書かれたものが、ほぼそのまま機械上で実行される」**のだ。

そこに、  
曖昧な翻訳も、意図しない最適化もない。

**コードは、機械の動きそのものだ。**

---

## アセンブリでは、意図しない魔法は起きない

高級言語では、  
- ラムダ式がキャプチャする変数  
- ガベージコレクタの遅延解放  
- コンパイラによるデッドコード除去  
- ランタイム最適化（JIT）

など、  
**設計者が意図していないレベルで、挙動が変わる**ことが珍しくない。

アセンブリには、これがない。

- 「PUSH EAX」と書けば、必ずEAXの値がスタックに積まれる  
- 「JMP label」と書けば、必ず無条件にジャンプする  
- 「MOV ECX, 0」と書けば、必ずECXは0になる

ここには、**魔法も助けもない。**

だからこそ、**アセンブリは透明なのだ。**

---

## 透明性の代償：すべての責任を負うということ

アセンブリは透明だ。  
だがその代償は重い。

- メモリリークは即座にバグになる  
- スタックオーバーフローも、バッファオーバーフローも、設計者の責任  
- 無限ループも、未定義動作も、すべて設計者の手による

つまり、  
**設計ミスが即座に、直接的に、破滅へとつながる。**

高級言語ではコンパイラやランタイムが緩衝材となるが、  
アセンブリにはそれがない。

**設計者は、自らの設計に対して、完全に責任を負う。**

---

## 透明性は設計力を鍛える

この厳しさこそが、  
アセンブリが設計者を成長させる理由である。

- どのデータがどこにあるかを常に意識する  
- レジスタ、メモリ、スタックの動きを設計する  
- 条件分岐とフロー制御を、物理的なジャンプ命令で設計する  
- リソース管理を、自らの手で完遂する

これらすべては、  
**高級言語においても必要な「設計の感覚」**を、  
最も純粋な形で鍛えるトレーニングになる。

---

## 透明なコードの美学

アセンブリを書くとは、  
単なる低レベル作業ではない。

それは、

- **何が起きるかを、すべて自分で定義する行為**  
- **動作を完全に理解した上で、動作を設計する行為**  
- **意図を隠すことなく、すべてを明示する行為**

である。

この**完全な可視性**こそが、  
アセンブリを「最も透明なコード」として尊ぶ理由だ。

---

## 透明性が必要な領域

現代においても、アセンブリ的な透明性は必要とされている。

- **OSカーネル設計**（メモリ保護、割り込みハンドリング）  
- **組み込みシステム**（リアルタイム制御、リソース制限）  
- **セキュリティ領域**（バイナリ解析、脆弱性研究）  
- **高頻度トレーディング**（極限まで削ぎ落とした最適化）  

これらの領域では、  
**「見えないもの」**が許されない。

透明性は、  
単なる理想論ではなく、**実用上の必須条件**なのだ。

---

## 結語：透明性とは、設計者が世界と正面から向き合う覚悟である

アセンブリは透明だ。  
そこには、言い訳も逃げ道もない。

- 何を設計したか  
- 何を設計しなかったか  
- どこで誤ったか

すべてが、動作という形で暴かれる。

だがそれは、恐れるべきことではない。  
それは、**設計者が「設計とは何か」を純粋な形で問い直すための祝福**なのだ。

> _"アセンブリとは、設計の純度を試す試練であり、透明性という名の戒律である。すべてを暴き、すべてを引き受けることで、初めて設計は本物になる。"_
アセンブリにおける条件分岐の美学



> _"選択すること。それは、世界に新たな秩序を与えること。"_  

プログラムとは、ただの順列ではない。  
そこには「選択」があり、「可能性」がある。  
そしてその分岐こそが、単なる手続きの羅列を、**動的な構造体**へと変換する。

アセンブリにおける**条件分岐**は、  
高級言語の`if`や`switch`とは異なり、  
**純粋で、裸の制御の姿**を見せる。

この章では、アセンブリ視点から、**条件分岐という設計美学**を掘り下げる。

---

## 条件分岐とは何か？

条件分岐とは、  
**「状態に応じて次に実行する命令を変えること」**である。

例（自然言語）：

- 「もし鍵を持っていたら、ドアを開ける」  
- 「もし雨が降っていたら、傘を持つ」

プログラムもこれと同じだ。  
しかし、アセンブリレベルではこの「もし」を、**物理的なジャンプ（分岐命令）**として記述する。

---

## アセンブリにおける条件分岐の基本

典型的なx86アセンブリの分岐はこうだ：

```assembly
CMP EAX, EBX    ; EAXとEBXを比較する
JE  label       ; 等しければlabelにジャンプ
```

意味：

- `CMP`は内部で引き算（EAX - EBX）を行い、フラグレジスタに結果をセットする  
- `JE`（Jump if Equal）は、その結果に応じてジャンプする

つまり、**比較は命令ではなく、状態変化のトリガー**であり、  
**ジャンプはその状態に応じた空間移動**である。

---

## 条件ジャンプ命令の多様性

x86には多種多様な条件ジャンプが存在する。

- `JE` (Jump if Equal)  
- `JNE` (Jump if Not Equal)  
- `JG` (Jump if Greater)  
- `JL` (Jump if Less)  
- `JGE` (Jump if Greater or Equal)  
- `JLE` (Jump if Less or Equal)  

これらは、**フラグレジスタ（ZF, SF, OF, CFなど）**にセットされたビットに基づいて決定される。

ここに、アセンブリ独特の**「状態を読む」**という美学が存在する。

---

## フラグレジスタ：静かなメッセンジャー

フラグレジスタは、演算結果に応じて自動的に設定される。

主要なフラグ：

- **ZF (Zero Flag)**：演算結果がゼロならセットされる  
- **SF (Sign Flag)**：結果が負ならセットされる  
- **CF (Carry Flag)**：繰り上がり・借り発生時にセットされる  
- **OF (Overflow Flag)**：符号付き演算でオーバーフローしたらセットされる

条件分岐は、この**フラグという小さな真実**を読み取り、  
次に進む道を選ぶ。

---

## 条件分岐の設計とは「世界線を選ぶこと」である

アセンブリにおいて、分岐を設計するとは：

- どの条件でどこへ飛ぶかを  
- 最小限かつ明示的に  
- しかも高速に設計することだ。

高級言語のような「曖昧な意図」では許されない。  
そこには、**確定した、ただ一つの「道の選択」**だけが存在する。

---

## 条件分岐が設計に与える影響

条件分岐は、単なる機能ではない。  
それは、**パイプライン設計・最適化・分岐予測**に直接影響を与える。

特に：

- **頻繁な分岐はCPUパイプラインを破壊しうる**  
- **予測可能な分岐は性能を向上させる**  
- **分岐の位置と頻度は、最適化対象である**

つまり、分岐を設計するとは、  
**「動作のリズムと未来の予測」を設計する**ことに他ならない。

---

## ARMにおける条件付き実行の美学

ARMアセンブリでは、  
命令自体に条件コードを付与できる。

例：

```assembly
ADDEQ R0, R1, R2  ; 前の演算結果がゼロなら加算
```

これにより、ジャンプせずとも条件付き動作が可能となる。

メリット：

- パイプライン破棄を減らせる  
- 命令フローがスムーズになる  
- 省エネルギーにつながる

ここに、**「分岐を隠し、流れを維持する」**という美学がある。

---

## 条件分岐を設計するということ

設計者にとって、条件分岐とは：

- 未来を予測すること  
- 最悪のパスを防ぐこと  
- 最小のコストで最大の柔軟性を得ること

である。

つまり、分岐設計はただの「if文」ではない。  
それは、**動的に変化する未来への設計思想そのもの**である。

---

## 結語：選択すること、それが設計である

アセンブリにおける条件分岐とは、  
単なる技法ではない。

それは、**設計者が「世界線」を選び取り、動作の未来を決定する行為**である。

- どこへ進むか  
- どの条件で進むか  
- どれだけ未来を予測するか

これらすべてが、たった一つのジャンプ命令に込められる。

> _"条件分岐とは、設計者が世界に与える小さな運命である。その一行で、世界は変わる。"_
RISC-Vの思想：最小命令セット主義



> _"最小とは、貧しさではない。最小とは、選び抜かれた強さである。"_  

RISC-V（リスク・ファイブ）。  
近年急速に存在感を高めているこのアーキテクチャは、  
単なる「新しい命令セット」ではない。  

それは、  
**「最小限であること」を徹底的に選び取った設計哲学**であり、  
同時に、**オープンソースハードウェア革命**の象徴でもある。

本稿では、RISC-Vアセンブリに触れながら、  
**最小命令セットが持つ意味と設計思想**を、深く掘り下げていく。

---

## RISC-Vとは何か？

RISC-Vは、カリフォルニア大学バークレー校によって設計された、  
**オープンで拡張可能な命令セットアーキテクチャ（ISA）**である。

特徴：

- RISC原則に則ったシンプルな命令セット  
- ライセンスフリー（誰でも使える）  
- 32bit、64bit、128bitアドレッシング対応  
- 必要最小限コア＋拡張モジュール（例えば浮動小数点演算、ベクトル演算）

つまり、RISC-Vとは、  
**「選び取る自由」「拡張する自由」「持たない自由」**を体現した設計なのである。

---

## なぜ「最小命令セット」が目指されたのか？

現代の多くのアーキテクチャ（x86、ARMなど）は、  
互換性維持や機能追加の結果、命令セットが肥大化している。

これに対してRISC-Vは：

- 設計の透明性  
- 検証の容易さ  
- 実装コストの削減  
- 教育・研究用途での使いやすさ

を重視し、  
**「本当に必要な最小限だけを標準コアとする」**  
という方針を打ち出した。

それは、設計そのものを洗練させ、  
**「無駄な歴史的負債を持たない」**未来志向のアーキテクチャを作る試みだった。

---

## RISC-Vアセンブリ：最小限で世界を作る

例えば、RISC-Vにおける加算はこう書く：

```assembly
ADD x5, x6, x7
```

意味：

- `x5 = x6 + x7`

また即値加算は：

```assembly
ADDI x5, x6, 10
```

このシンプルさ。  
この一貫性。

RISC-Vでは、演算命令、ロード/ストア命令、制御フロー命令が、  
**すべて予測可能なフォーマットに統一**されている。

---

## 命令セット設計における「縮減」という哲学

RISC-V設計者たちは、こう考えた。

- 機能は少なければ少ないほど良い  
- 複雑な機能は、必要な場合に拡張として追加すればよい  
- 実装者に無理強いをしない

この設計思想により、  
RISC-Vは**「本当に必要なものだけを持つコア」**を定義し、  
それ以外は完全にオプショナルとした。

- 整数演算だけのI拡張  
- 浮動小数点演算のF/D拡張  
- 原子命令のA拡張  
- 圧縮命令のC拡張  
- ベクトル演算のV拡張

**コアは最小、必要に応じて追加する。**  
この柔軟性が、設計を未来に開いた。

---

## オープンソースとしてのRISC-V

RISC-Vが真に革命的だったのは、  
**ISA（命令セット）そのものをオープンにした**点だ。

従来、CPUアーキテクチャは：

- 設計情報は非公開  
- ライセンス費用が高額  
- 実装は限られた企業だけ

という「閉ざされた世界」だった。  

RISC-Vはこれを打ち破った。

- 誰でも命令セットを利用できる  
- 自由にカスタムコアを設計できる  
- 研究者も学生も使える

**設計を共有し、知を解放する。**  
RISC-Vは、ハードウェア界に「オープンソース」の精神を持ち込んだ。

---

## RISC-Vにおける「透明なプログラミング体験」

アセンブリを書くとき、RISC-Vはとにかく明快だ。

例：メモリから値をロードして加算する

```assembly
LW x5, 0(x6)  ; x5 = *(x6 + 0)
ADDI x5, x5, 1
SW x5, 0(x6)
```

- ロード  
- 加算  
- ストア

この一連の流れが、  
**ほぼ機械の動作そのままに記述されている。**

ここに余計な抽象も、過剰な複雑性もない。  
**透明なプログラミング体験。**

それがRISC-Vアセンブリの美しさだ。

---

## RISC-Vは未来に耐えるか？

もちろん、批判も存在する。

- 命令セットがシンプルすぎて、最適化の自由度が限られる可能性  
- セキュリティ拡張（例：メモリ保護機構）への適応コスト  
- 巨大資本を持つ他アーキテクチャ（ARM, x86）とのエコシステム差

だが、それでもRISC-Vは着実に浸透し始めている。  
特に：

- 組み込み機器  
- IoT  
- FPGA向けコア  
- 教育・研究用途

では、**すでに「標準」になりつつある。**

そしてなにより、  
**オープンであることの力**は、時間と共に蓄積していく。

---

## 結語：最小とは、設計者の意志の純度である

RISC-Vは、単なる技術選択肢ではない。  
それは、**設計における純粋性への挑戦**だ。

- 無駄を削ぎ  
- 必要を選び  
- 自由を与え  
- 未来に開く

最小であることは、  
設計を怠ることではない。  
最小であることは、  
設計を極限まで洗練することなのだ。

> _"最小命令セットとは、貧しさではない。それは、設計者の意図を最も強く、最も澄んだ形で世界に刻むための選択である。"_