Skip to content

Instantly share code, notes, and snippets.

View rui314's full-sized avatar

Rui Ueyama rui314

  • Blue Whale Systems
  • Tokyo
View GitHub Profile
@rui314
rui314 / Dockerfile
Last active September 17, 2019 11:01
FROM ubuntu:latest
RUN apt update && apt install -y gcc make git binutils libc6-dev gdb
RUN adduser --disabled-password --gecos '' user
USER user
WORKDIR /home/user

MIPSのABIは変だという話をこないだのシステムプログラミング会でしたら、ややザワッとしたので、なにがおかしいのかというのをちょっとまとめてみました。まとめてみて思いましたが、やっぱりMIPSのELFファイルはちょっと変です。

謎のmixed endianフィールド

これが僕は一番ひどいと思ったものです。

ファイルにマルチバイトの数値を保存するときはエンディアンというものが問題になります。たとえば0xBEEFという2バイトの数を保存するときは、1バイト目にBE、2バイト目にEFを書くか、逆順で書くかは、ただの決まり事でどっちでもいいわけですが、書く側と読む側で認識があっていないと困ります。世の中的にはリトルエンディアン(下位バイトから書く)のが主流ですがビッグエンディアンなシステムもあります。

それがですね、MIPSのELFヘッダのr_infoという64ビットのフィールドはリトルエンディアンでもビッグエンディアンでもない謎なエンコーディングになっています。具体的には下位32ビットが最初にリトルエンディアンで書かれていて、ビッグエンディアンでエンコードされた上位32ビットがそれに続くという構成になっています。つまりリトルエンディアンだとABCD EFGH、ビッグエンディアンだとHGFE DCBAとなるところが、MIPSのmixed endianだとEFGH DCBAというふうにファイルに書かれていることになります。

# 最初になにをやるのかをコメントで書いておくとコードがぐっとわかりやすくなります。
# コードを書いているときは「ここでは〇〇をやろう」と考えながら書いているわけだけど、
# いったんコードになってしまうとそのメタな情報はなくなってしまうので、
# 読者は「結局これは何をやっているのか」というのを推測しながら読むことになってしまいます。
# コメントで意図を説明しておけば推測に頼らずにすむし、変なコードがあっても意図通り
# なのかバグなのか判別がつきやすい。
#
# なおこれはトップレベルのメソッドです。どういうレイアウトがいいかは
# 他にどんなコードがあるかによりますが、元々の例では単体のこのコードしかないので、
# 単純に引数の合計を計算するだけのものにクラスは不要でしょう。

A C compiler for Brainfuck

I want to share my friend's crazy project because it demonstrates how a simple Turing-machine-like programming language is actually equivalent to usual real-world computers.

I think we all know the theory that all Turing complete programming languages are equivalent in terms of their powers. If languages A and B are Turing complete, A can emulate B and vice versa. But that's not obvious at all. How can a simple programming model like Turing Machine can run "real" programs such as ones that run on a general-purpose PC? If it is possible in theory, it can be demonstrated.

@rui314
rui314 / gist:2018964
Created March 12, 2012 00:51
N queen
int print_board(int board[][8]) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (board[i][j])
printf("Q ");
else
printf(". ");
}
printf("\n");
}