- 技術 💻
RISC-Vとは|ARM・x86との違いを逆アセンブルとqemuで実測
結論
RISC-V(リスクファイブ)は、誰でも使用料なしで使えるオープンな命令セット(ISA=CPUとソフトの間の約束ごと)です。ARM・x86 との違いは「仕様が公開され、自由に実装できる」点と、「小さな基本命令に、必要な拡張を足す」作りにあります。
この記事でわかること
- RISC-V・ARM・x86 の違いを、同じ C の逆アセンブルで比べた結果
- RV64GC・RVA23 などの名前の読み方と、32ビット固定長・圧縮命令の実測
- qemu で RISC-V のプログラムを動かす手順と、よくあるエラーの原文
CPU は、決められた命令しか実行できません。その「どんな命令があり、どうビットで表すか」の決まりが命令セット(ISA)です。RISC-V は、この決まりを誰でも読めて、誰でも使える形で公開しています。
flowchart TD
SRC[C などのソースコード] --> CC[コンパイラ<br>-march=rv64gc]
CC --> BIN[RISC-V の機械語]
SPEC[仕様 RISC-V ISA<br>RISC-V International] -.決める.-> BIN
BIN --> HW1[各社のCPU<br>コアIP・自社設計]
BIN --> HW2[qemu などの<br>エミュレーター]
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| RISC-Vとは | オープンで使用料のかからない命令セット(ISA)。CPU の製品名ではない | RISC-Vとは |
| RISC-V と ARM の違い | ARM は Arm 社がライセンスで提供。RISC-V は仕様が公開され、誰でも実装できる | ARM・x86との違い |
| RISC-V は無料か | ISA の利用は無料。CPU の設計(コアIP)やチップは別に費用がかかる | オープンなISAとライセンス |
| RV64GC の意味 | 64ビットの基本整数命令(I)に M・A・F・D・C などの拡張を足した組み合わせ | 拡張の名前の読み方 |
| 命令の長さ | 基本は32ビット固定長。C拡張で16ビットの命令を混ぜられる | 32ビット固定長 |
| 手元で動かすには | クロスコンパイラでビルドし、qemu-riscv64 で実行する | qemuで実行する |
| どこで使われているか | マイコン(ESP32-C3 など)から、Linux が動く64ビットの CPU まで | 採用製品と動向 |
| RISC-V はARMより速いか | ISA だけでは決まらない。CPU の設計・製造・コンパイラで変わる | よくあるエラーと誤解 |
確認環境:Ubuntu 24.04.5 LTS(x86_64、Intel Xeon 2.10GHz・2コア)の上で、Ubuntu の公式リポジトリから apt-get download で取得した .deb(gcc-13-riscv64-linux-gnu 13.3.0・binutils-riscv64-linux-gnu 2.42・libc6-riscv64-cross 2.39・qemu-user 8.2.2、比較用に gcc-13-aarch64-linux-gnu 13.3.0)を dpkg-deb -x で作業用のフォルダーに展開して使いました(システムへのインストールと binfmt の登録はしていません)。x86-64 側はホストの GCC 13.3.0 です。自分で書いた C のプログラムを3つの CPU 向けにビルドし、objdump の逆アセンブル、size でのサイズ、qemu-riscv64・qemu-aarch64 での実行結果を並べています。コードの大きさの比較には、EEMBC の CoreMark(GitHub の eembc/coremark、コミット 1f483d5)をコンパイルしてサイズだけを測りました。仕様の内容は RISC-V International の ISA マニュアル(v20260120)と公式サイト、採用製品・動向は各社・各団体の公式発表で確かめた範囲だけを書いています。図は mermaid で描画を確かめました(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「RISC-Vとは|ARM・x86との違いを逆アセンブルとqemuで実測」
RISC-Vとは(命令セット=CPUとソフトの約束ごと)
この節では、RISC-V が「何」なのか、CPU や ARM・x86 とどういう関係にあるのかが分かります。
RISC-V は、CPU が理解する命令の種類と、その命令をビットでどう表すかを決めた仕様(命令セットアーキテクチャ、ISA)です。 読み方は「リスクファイブ」で、仕様書にも "pronounced risk-five" と書かれています。RISC-V という名前の CPU の製品が1つあるわけではなく、この仕様に従って各社や大学が CPU を設計します。
- ISA(命令セット):「足し算は add、メモリから読むのは lw」のような命令の一覧と、そのビットの並び。ソフト(コンパイラ)とハード(CPU)の間の約束。
- CPU(実装):ISA の約束どおりに命令を実行する回路。同じ ISA でも、速さ・消費電力・大きさは設計によって大きく違う。
- RISC:命令を単純にして、1つ1つを速く実行するという設計の考え方。RISC-V はカリフォルニア大学バークレー校で続いた RISC の研究の5代目にあたるので「V(5)」が付いています。
RISC-V International の公式サイトによると、RISC-V はバークレー校の研究者が 2010年5月に始めた命令セットです。2015年に RISC-V Foundation が36の創設メンバーで発足し、2020年3月にスイスで RISC-V International Association として法人化しました。今の仕様は、この非営利団体が管理しています。
手元で、同じ C のプログラムを RISC-V・ARM(AArch64)・x86-64 向けにビルドして動かすと、出力はまったく同じでした。ソースコードは同じでも、出来上がる機械語は CPU ごとに別物で、それぞれの ISA に合わせて作られます。
$ qemu-riscv64 -L $R/usr/riscv64-linux-gnu ./isa-rv # RISC-V(qemu で実行)
add3(1,2,3)=6 counter=3 find(5)=4 find(7)=-1 twice_plus1(20)=41
sizeof(long)=8 sizeof(void*)=8
endian: first byte=0x44
$ qemu-aarch64 -L $R/usr/aarch64-linux-gnu ./isa-a64 # ARM(AArch64、qemu で実行)
add3(1,2,3)=6 counter=3 find(5)=4 find(7)=-1 twice_plus1(20)=41
...
$ ./isa-x86 # x86-64(そのまま実行)
add3(1,2,3)=6 counter=3 find(5)=4 find(7)=-1 twice_plus1(20)=41
...
3つとも long とポインタは8バイト、0x11223344 の先頭のバイトは 0x44(リトルエンディアン)でした。
RISC-VとARM・x86の違い(比較表)
この節では、RISC-V・ARM・x86 の違いを、仕様の持ち主・命令の長さ・手元で測った数字で比べた結果が分かります。
いちばん大きな違いは「誰が仕様を持ち、どういう条件で使えるか」です。 命令の作りの違いは、そのあとに来ます。
| 項目 | RISC-V | ARM(AArch64) | x86-64 |
|---|---|---|---|
| 仕様を管理する所 | RISC-V International(非営利) | Arm 社 | Intel・AMD |
| 使う条件 | ISA はロイヤリティなし・公開ライセンス | Arm 社とのライセンス契約 | 主に Intel・AMD が自社の CPU で使う |
| 命令の長さ | 32ビット固定(C拡張で16ビットを混在) | 32ビット固定 | 1〜15バイトの可変長 |
| 作りの考え方 | 小さな基本命令+選べる拡張 | 版(Armv8・v9)ごとに機能をまとめて定義 | 互換を保ちながら命令を追加 |
| メモリの読み書き | lw・sw などの専用命令だけ(ロード・ストア型) | ldr・str だけ(ロード・ストア型) | add などがメモリを直接読み書きできる |
| 手元の4関数の大きさ | 58バイト(RV64GC)/96バイト(RV64G) | 104バイト | 76バイト |
| CoreMark の .text(-O2) | 7,460バイト(RV64GC) | 8,772バイト | 8,471バイト |
下の2行は、この記事で実際にビルドして測った値です(次の節以降で原文を示します)。x86-64 の値には、Ubuntu の GCC が既定で付ける endbr64(関数の先頭に置く4バイトの命令)が含まれています。
RISC-V が向く考え方
自分で CPU を設計したい・独自命令を足したい
ISA の使用料を払いたくない
必要な拡張だけの小さな CPU にしたい
ARM・x86 が向く考え方
すでにあるソフト・OS・ツールをそのまま使いたい
完成した CPU・コアを買って使いたい
サポートの窓口を1社にまとめたい
オープンなISAの意味とライセンス(無料なのは何か)
この節では、「RISC-V はオープン」「無料」が、具体的に何を指しているのかが分かります。
無料なのは「ISA を使う権利」です。 RISC-V International は公式サイトで、RISC-V を "an open, royalty-free ISA" と説明し、"anyone may leverage RISC-V as a building block in their open or proprietary solutions and services"(誰でも、オープンなものにも、独自の製品やサービスにも、RISC-V を部品として使える)と書いています。仕様書(ISA マニュアル)は、版 2.2 の前書きで Creative Commons Attribution 4.0 のライセンスで公開すると書かれ、以降の版も同じライセンスとされています。
| もの | 無料か | 説明 |
|---|---|---|
| ISA の仕様書を読む | 無料 | docs.riscv.org で公開。誰でも読める |
| ISA に従って CPU を設計する | 使用料なし | ISA のロイヤリティは発生しない |
| 他社が設計したコア(IP)を使う | 多くは有料 | コアの設計データは各社の製品。条件は各社が決める |
| オープンソースのコアを使う | ライセンス次第 | コアごとに決められたライセンスに従う |
| チップを作る(製造) | 有料 | 設計・検証・製造の費用は ISA と関係なくかかる |
ARM の場合、Arm 社は公式サイトで、大企業向けの Arm Total Access、スタートアップや中小企業向けの Arm Flexible Access(製造費はテープアウト時にプロジェクトごと)、大学向けの Arm Academic Access という契約の形を案内しています。「Arm の技術を使うには Arm 社との契約が入口」、「RISC-V は契約なしに仕様を使える」という違いです。
- オープンなのは仕様です。RISC-V の CPU がすべてオープンソースの回路というわけではありません。独自に設計し、設計データを公開しない RISC-V のコアも多くあります。
- 独自の命令を足すこともできます。仕様では、標準でない拡張は「X」で始まる名前にする決まりです。
拡張の名前の読み方(RV64GC・RVA23・Zba)
この節では、「RV64GC」「rv64imafdc_zicsr_zifencei」「RVA23」のような名前を、仕様の決まりと実物で読めるようになります。
RISC-V は「基本の整数命令(I)」に「拡張」を足して使います。名前は、ビット幅+基本命令+拡張の文字の並びです。 仕様の命名規則(ISA マニュアルの「ISA Extension Naming Conventions」)によると、名前は RV32I・RV32E・RV64I・RV64E のどれかで始まり、大文字と小文字は区別しません。
| 文字 | 意味 | 手元の例 |
|---|---|---|
| RV32・RV64 | 整数レジスタの幅(32ビット・64ビット) | riscv64 の Linux は RV64 |
| I・E | 基本の整数命令(E はレジスタ16本の組み込み向け) | add・addi・lw・sw・beq・jal |
| M | 整数の掛け算・割り算 | mul・div |
| A | アトミック命令(複数コアでの排他) | amoadd・lr・sc |
| F・D | 単精度・倍精度の浮動小数点 | fadd.d |
| C | 16ビットの圧縮命令 | c.add・c.lw |
| G | IMAFD+Zicsr+Zifencei の略 | RV64G |
| V | ベクトル命令 | vadd.vv・vle32.v |
| Z〜 | 小さな標準拡張(Zba・Zbb はビット操作) | sh2add・cpop |
仕様には "We have also defined an abbreviation "G" to represent the "IMAFDZicsr_Zifencei" base and extensions" とあります。つまり RV64GC は「RV64I+M・A・F・D・Zicsr・Zifencei+C」で、Linux が動く64ビットの RISC-V の標準的な組み合わせです。
実物:ELF ファイルに書かれた ISA の名前
GCC が作るファイルには、どの拡張を使ったかが書き込まれています。readelf -A で読めます。
$ riscv64-linux-gnu-gcc-13 -Q --help=target | grep -E -- '-march=|-mabi='
-mabi= lp64d
-march= rv64imafdc_zicsr_zifencei
$ riscv64-linux-gnu-gcc-13 -O2 -march=rv64g -mabi=lp64d -c isa.c -o isa-g.o
$ riscv64-linux-gnu-readelf -A isa-g.o | grep arch
Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_zicsr2p0_zifencei2p0_zmmul1p0"
$ riscv64-linux-gnu-gcc-13 -O2 -march=rv64gc_zba_zbb -c isa.c -o isa-b.o
$ riscv64-linux-gnu-readelf -A isa-b.o | grep arch
Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0"
- Ubuntu の RISC-V 向け GCC の既定は
rv64imafdc_zicsr_zifencei(=RV64GC)と、ABI(関数の呼び出し方の決まり)lp64dでした。 i2p1は「I 拡張の版 2.1」です。仕様では、版の大きい番号と小さい番号を「p」でつなぎます。-march=rv64gと書くと、G がi・m・a・f・d・zicsr・zifenceiに展開されました。- 拡張どうしは「_」でつなぎます。
rv64gc_zba_zbbのように、Z で始まる拡張は「_」で区切って後ろに足します。
プロファイル(RVA23)とは
拡張を自由に選べると、OS やアプリは「どの拡張がある前提で作るか」に困ります。そこで、決まった拡張の組み合わせに名前を付けたのがプロファイルです。 RISC-V International は2024年10月21日、64ビットのアプリケーションプロセッサー向けのプロファイル RVA23 の批准を発表しました。発表では、ベクトル(V)とハイパーバイザー(H)の拡張が必須とされています。同じ発表の中で Google の担当者は、RVA23 が Android の RISC-V の ABI の基準になったと述べています。
RISC-V向けにクロスコンパイルする(gcc-riscv64-linux-gnu)
この節では、x86 のパソコンの上で RISC-V 用のプログラムを作る(クロスコンパイルする)手順が分かります。
Ubuntu では、RISC-V 向けのクロスコンパイラ(gcc-riscv64-linux-gnu)と、ユーザーモードの qemu(qemu-user)を入れると、x86 のパソコンで RISC-V のプログラムをビルドして動かせます。 一般的な入れ方は次のとおりです。
sudo apt install gcc-riscv64-linux-gnu qemu-user
riscv64-linux-gnu-gcc hello.c -o hello-rv
qemu-riscv64 -L /usr/riscv64-linux-gnu ./hello-rv
この記事では、ほかの作業と環境を分けるため、apt-get download で .deb を取得し、dpkg-deb -x で作業用のフォルダー(以下 $R)に展開して使いました。この場合は、ライブラリの場所を GCC に教える --sysroot が要ります。
.deb を取得して展開する
gcc-13-riscv64-linux-gnu・cpp-13-riscv64-linux-gnu・binutils-riscv64-linux-gnu・libc6-dev-riscv64-cross などと qemu-user を apt-get download し、dpkg-deb -x 〜.deb $R で展開した。
共有ライブラリの場所を通す
展開したアセンブラは libopcodes-2.42-riscv64.so を探すので、LD_LIBRARY_PATH=$R/usr/lib/x86_64-linux-gnu を設定した。
--sysroot を付けてビルドする
riscv64-linux-gnu-gcc-13 --sysroot=$R hello.c -o hello-rv。付けないと、リンカーが /usr/riscv64-linux-gnu/lib/libc.so.6 を見つけられずに止まった。
file で中身を確かめる
file hello-rv で「UCB RISC-V, RVC, double-float ABI」と出れば、RISC-V(C拡張・倍精度の ABI)向けにできている。
qemu-riscv64 で実行する
-L で RISC-V 用のライブラリの場所を渡す。静的リンク(-static)なら -L なしで動く。
$ riscv64-linux-gnu-gcc-13 --sysroot=$R hello.c -o hello-rv
$ file hello-rv
hello-rv: ELF 64-bit LSB pie executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, ..., for GNU/Linux 4.15.0, not stripped
$ qemu-riscv64 -L $R/usr/riscv64-linux-gnu ./hello-rv
hello RISC-V
同じ手順で gcc-13-aarch64-linux-gnu も展開し、ARM(AArch64)向けのビルドと qemu-aarch64 での実行も並べました。ビルドの考え方(コンパイル→リンク)は、関連記事「コンパイルとは|意味・インタプリタとの違いを6言語の実行で解説」で扱っています。
逆アセンブルでRISC-V・ARM・x86を比べる(add・addi・lw・sw・beq・jal)
この節では、同じ C の関数が、RISC-V・ARM・x86 でどんな命令になるのかを、objdump -d の原文で比べた結果が分かります。
比べたのは、次の4つの関数です(-O2、関数が1つにまとめられないよう noinline を付けています)。
int counter; /* グローバル変数(メモリ上) */
__attribute__((noinline)) long add3(long a, long b, long c) { return a + b + c; }
__attribute__((noinline)) void bump(void) { counter = counter + 1; }
__attribute__((noinline)) int find(const int *a, int n, int key) {
for (int i = 0; i < n; i++)
if (a[i] == key) return i;
return -1;
}
__attribute__((noinline)) long twice_plus1(long x) { return add3(x, x, 1); }
RISC-V(RV64G・圧縮命令なし)
左の16進数が機械語、右がその読み方です。圧縮命令を使わない -march=rv64g では、すべての命令が8桁(4バイト=32ビット)になりました。
$ riscv64-linux-gnu-objdump -d isa-rvg
00000000000008fc <add3>:
8fc: 00b50533 add a0,a0,a1
900: 00c50533 add a0,a0,a2
904: 00008067 ret
0000000000000908 <bump>:
908: 00001717 auipc a4,0x1
90c: 70470713 addi a4,a4,1796 # 200c <counter>
910: 00072783 lw a5,0(a4)
914: 0017879b addiw a5,a5,1
918: 00f72023 sw a5,0(a4)
91c: 00008067 ret
0000000000000920 <find>:
920: 02b05463 blez a1,948 <find+0x28>
924: 00050793 mv a5,a0
928: 00000513 li a0,0
92c: 00c0006f j 938 <find+0x18>
930: 0015051b addiw a0,a0,1
934: 00a58a63 beq a1,a0,948 <find+0x28>
938: 0007a703 lw a4,0(a5)
93c: 00478793 addi a5,a5,4
940: fec718e3 bne a4,a2,930 <find+0x10>
944: 00008067 ret
948: fff00513 li a0,-1
94c: 00008067 ret
0000000000000950 <twice_plus1>:
950: 00050593 mv a1,a0
954: 00100613 li a2,1
958: fa5ff06f j 8fc <add3>
ret・mv・li・j は読みやすくするための別名(疑似命令)です。-M no-aliases を付けると、本当の命令が見えます。
$ riscv64-linux-gnu-objdump -d -M no-aliases isa-rvg
904: 00008067 jalr zero,0(ra)
950: 00050593 addi a1,a0,0
954: 00100613 addi a2,zero,1
958: fa5ff06f jal zero,8fc <add3>
上から順に、ret は jalr zero,0(ra)(ra のアドレスへ戻る)、mv は addi a1,a0,0、li は addi a2,zero,1、j は戻り先を残さない jal zero,… でした。
main から関数を呼ぶところは、戻り先を ra レジスタに残す jal になっていました。
706: 190000ef jal 896 <bump>
718: 178000ef jal 890 <add3>
732: 174000ef jal 8a6 <find>
ARM(AArch64)と x86-64
$ aarch64-linux-gnu-objdump -d isa-a64 # ARM(AArch64)
00000000000009a0 <add3>:
9a0: 8b010000 add x0, x0, x1
9a4: 8b020000 add x0, x0, x2
9a8: d65f03c0 ret
00000000000009b0 <bump>:
9b0: 90000101 adrp x1, 20000 <__data_start>
9b4: b9401420 ldr w0, [x1, #20]
9b8: 11000400 add w0, w0, #0x1
9bc: b9001420 str w0, [x1, #20]
9c0: d65f03c0 ret
$ objdump -d -M intel isa-x86 # x86-64
0000000000001290 <add3>:
1290: f3 0f 1e fa endbr64
1294: 48 01 f7 add rdi,rsi
1297: 48 8d 04 17 lea rax,[rdi+rdx*1]
129b: c3 ret
00000000000012a0 <bump>:
12a0: f3 0f 1e fa endbr64
12a4: 83 05 69 2d 00 00 01 add DWORD PTR [rip+0x2d69],0x1 # 4014 <counter>
12ab: c3 ret
| やっていること | RISC-V | ARM(AArch64) | x86-64 |
|---|---|---|---|
| レジスタどうしの足し算 | add a0,a0,a1 |
add x0, x0, x1 |
add rdi,rsi(2つの形) |
| 定数を足す | addi・addiw |
add w0, w0, #0x1 |
add …,0x1 |
| メモリから読む・書く | lw・sw |
ldr・str |
add が直接メモリを書き換える |
| 比べて分岐 | beq・bne(比べると同時に飛ぶ) |
cmp+b.eq |
cmp+je |
| 関数を呼ぶ | jal(戻り先は ra) |
bl(戻り先は x30) |
call(戻り先はスタック) |
1bump は3命令と1命令
RISC-V と ARM は「読む→足す→書く」の3命令。x86-64 は add DWORD PTR [rip+…],0x1 の1命令でメモリを直接書き換えた。
2フラグが無い
RISC-V の beq a1,a0,… は2つのレジスタを比べてそのまま分岐した。ARM・x86 は cmp で条件フラグを立ててから分岐する。
3w の付く命令
RV64 で int(32ビット)を足すと addiw になった。32ビットで計算し、結果を64ビットに符号拡張する命令。
RISC-Vの命令は32ビット固定長(機械語をビットで分解する)
この節では、RISC-V の機械語が32ビットの中でどう区切られているかを、実際の命令をビットに分解して確かめた結果が分かります。
仕様には "The base RISC-V ISA has fixed-length 32-bit instructions that must be naturally aligned on 32-bit boundaries." とあり、基本の命令は32ビット固定長です。 32ビットの命令は下位2ビットが必ず 11 で、16ビットの圧縮命令は 00・01・10 を使います。CPU は、先頭の2ビットを見るだけで命令の長さが分かります。
逆アセンブルに出てきた機械語を、自作の Python のスクリプト(各ビットの位置を取り出すだけのもの)で分解しました。
$ python3 decode.py 00b50533 70470713 00072783 00f72023 00a58a63 190000ef fa5ff06f 00001717
00b50533 00000000101101010000010100110011 R型 funct7=0000000 rs2=a1 rs1=a0 funct3=000 rd=a0 opcode=0110011
70470713 01110000010001110000011100010011 I型 imm=1796 rs1=a4 funct3=000 rd=a4 opcode=0010011
00072783 00000000000001110010011110000011 I型 imm=0 rs1=a4 funct3=010 rd=a5 opcode=0000011
00f72023 00000000111101110010000000100011 S型 imm=0 rs2=a5 rs1=a4 funct3=010 opcode=0100011
00a58a63 00000000101001011000101001100011 B型 imm=20 rs2=a0 rs1=a1 funct3=000 opcode=1100011
190000ef 00011001000000000000000011101111 J型 imm=400 rd=ra opcode=1101111
fa5ff06f 11111010010111111111000001101111 J型 imm=-92 rd=zero opcode=1101111
00001717 00000000000000000001011100010111 U型 imm=0x1 rd=a4 opcode=0010111
| 形式 | 使う命令 | 中身 | 手元の確認 |
|---|---|---|---|
| R型 | add・sub など | レジスタ3つ(rd・rs1・rs2) | add a0,a0,a1 |
| I型 | addi・lw・jalr | レジスタ2つ+12ビットの定数 | addi の 1796、lw の 0 |
| S型 | sw など | 書く値とアドレスのレジスタ+定数 | sw a5,0(a4) |
| B型 | beq・bne など | 比べる2つ+飛び先(±4KiB) | 0x934 から +20 で 0x948 |
| U型・J型 | auipc・lui・jal | 大きな定数・飛び先(jal は±1MiB) | 0x706 から +400 で 0x896 |
- rd・rs1・rs2 の場所が、どの形式でも同じビット位置にあります。 分解した表でも、rs1 は常に15〜19ビット目でした。仕様は "The RISC-V ISA keeps the source (rs1 and rs2) and destination (rd) registers at the same position in all formats to simplify decoding." と、解読を単純にするための作りだと説明しています。
- B型・J型の飛び先は、命令の位置からの差(相対値)です。
beqの imm=20 は、0x934+20=0x948 で、逆アセンブルの<find+0x28>と一致しました。 auipc+addiの2命令で、グローバル変数counterのアドレスを作っています。12ビットの定数では遠くのアドレスを表せないためです。
x0 は常に0
仕様は "Register x0 is hardwired with all bits equal to 0." としています。x0 に書き込もうとしても、読むと0のままでした。
long r;
__asm__ volatile ("addi x0, x0, 5\n\t" /* x0 に 5 を足して書き込もうとする */
"mv %0, x0" : "=r"(r)); /* x0 を読む */
printf("x0 = %ld\n", r);
$ qemu-riscv64 -L $R/usr/riscv64-linux-gnu ./x0
x0 = 0
仕様では、rd が x0 の addi は何もしない命令(HINT)として扱われ、addi x0, x0, 0 が NOP(何もしない命令)の正式な形です。mv(=addi rd, rs, 0)や li(=addi rd, zero, 定数)のように、x0 を「0の入ったレジスタ」として使うことで、命令の種類を少なくしています。
圧縮命令(C拡張)でサイズはどれだけ減るか(実測)
この節では、16ビットの圧縮命令を使うと、プログラムの大きさが実際にどれだけ変わるかが、3つの測り方で分かります。
仕様は C 拡張について "Typically, 50%-60% of the RISC-V instructions in a program can be replaced with RVC instructions, resulting in a 25%-30% code-size reduction." と書いています。手元で測ると、命令の約54%が16ビットになり、コードは約27%小さくなりました。
1. 同じ関数を RV64G と RV64GC で
RV64GC(既定)で同じ isa.c をビルドすると、多くの命令が4桁(2バイト)になりました。
$ riscv64-linux-gnu-objdump -d isa-rv # RV64GC
0000000000000890 <add3>:
890: 952e add a0,a0,a1
892: 9532 add a0,a0,a2
894: 8082 ret
0000000000000896 <bump>:
896: 00001717 auipc a4,0x1
89a: 77670713 addi a4,a4,1910 # 200c <counter>
89e: 431c lw a5,0(a4)
8a0: 2785 addiw a5,a5,1
8a2: c31c sw a5,0(a4)
8a4: 8082 ret
$ riscv64-linux-gnu-objdump -d -M no-aliases isa-rv
890: 952e c.add a0,a1
892: 9532 c.add a0,a2
894: 8082 c.jr ra
関数ごとの大きさ(nm -S で測ったバイト数)です。
| 関数 | RV64G | RV64GC | AArch64 | x86-64 |
|---|---|---|---|---|
| add3 | 12 | 6 | 12 | 12 |
| bump | 24 | 16 | 20 | 12 |
| find | 48 | 30 | 60 | 38 |
| twice_plus1 | 12 | 6 | 12 | 14 |
| 合計 | 96 | 58 | 104 | 76 |
2. CoreMark をビルドして .text を比べる
もう少し大きなコードとして、CPU の性能比較に使われる CoreMark の本体(core_list_join・core_main・core_matrix・core_state・core_util の5ファイル)をコンパイルし、size -A で .text の合計を測りました(プラットフォーム依存の core_portme は除く)。
| 構成 | -O2 の .text | -Os の .text | RV64G との差(-O2) |
|---|---|---|---|
| RV64G(圧縮なし) | 10,188 | 7,988 | 基準 |
| RV64GC | 7,460 | 5,808 | 26.8%小さい |
| RV64GC+Zba・Zbb・Zbs | 7,028 | 5,600 | 31.0%小さい |
| AArch64 | 8,772 | 6,504 | 13.9%小さい |
| x86-64 | 8,471 | 5,654 | 16.9%小さい |
RV64GC の命令の数を長さ別に数えると、次のとおりでした。
$ riscv64-linux-gnu-objdump -d rv64gc-O2/core_*.o | (2バイトと4バイトの命令を数える)
rv64gc-O2: 2byte=1364 4byte=1183 total=2547 ratio=53.6%
rv64gc-Os: 2byte=1090 4byte=907 total=1997 ratio=54.6%
rv64g-O2: 2byte=0 4byte=2547 total=2547 ratio=0.0%
RV64G と RV64GC で、命令の数はどちらも2,547個で同じでした。 仕様の "each RVC instruction expands into a single 32-bit instruction"(圧縮命令は、それぞれ1つの32ビットの命令に対応する)のとおり、圧縮命令は「同じ命令の短い書き方」で、命令の数は変わらず、バイト数だけが減っています。
3. glibc(libc.so.6)全体
Ubuntu の glibc 2.39 の libc.so.6 を3つの CPU で比べました。RISC-V 版は C 拡張を使ってビルドされています。
| libc.so.6 | .text のバイト数 | 補足 |
|---|---|---|
| riscv64 | 927,824 | 命令の47.1%(148,473個)が16ビット |
| arm64 | 1,161,248 | すべて32ビット |
| amd64 | 1,603,641 | CPU の機能ごとの最適化版の関数を多く含む |
glibc は CPU ごとに入っている最適化版の関数(x86-64 なら AVX2 用など)の数が違うため、この差は ISA の違いだけではありません。ISA どうしを公平に比べるなら、同じソースを同じコンパイラ・同じ最適化で比べる(1と2)のが確実です。
- 圧縮命令が使えるのは、よく使う形に限られます。仕様によると、一部の形式は32本のうち8本のレジスタしか指定できず、
c.beqz・c.bnezの飛び先は±256バイト、c.jは±2KiB までです。
qemuでRISC-Vのプログラムを実行する(qemu-riscv64)
この節では、RISC-V の実機が無くても、qemu で RISC-V のプログラムを動かす方法と、そのとき何が起きているかが分かります。
qemu-riscv64(qemu-user)は、RISC-V の命令をその場で x86 の命令に変換しながら実行し、システムコールはホストの Linux に渡します。 そのため、RISC-V の Linux 向けのプログラムを、x86 の Linux の上でそのまま動かせます。
$ qemu-riscv64 --version
qemu-riscv64 version 8.2.2 (Debian 1:8.2.2+ds-0ubuntu1.18)
$ qemu-riscv64 -cpu help
any
max
rv64
shakti-c
sifive-e51
sifive-u54
thead-c906
veyron-v1
x-rv128
静的リンクなら -L なしで動く
$ riscv64-linux-gnu-gcc-13 --sysroot=$R -static -O2 hello.c -o hello-rv-static
$ ls -l hello-rv hello-rv-static
8488 hello-rv
556080 hello-rv-static
$ qemu-riscv64 ./hello-rv-static
hello RISC-V
C のライブラリを中に含むため 8,488 バイトから 556,080 バイトになりましたが、-L なしで動きました。
-strace でシステムコールを見る
-strace を付けると、RISC-V のプログラムが出したシステムコールが表示されます。最後は write で文字を出し、exit_group で終わっていました。
$ qemu-riscv64 -strace ./hello-rv-static
6114 brk(0x00000000000ab000) = 0x00000000000ab000
6114 mprotect(0x000000000007e000,16384,PROT_READ) = 0
6114 fstat(1,0x00002aaaab2a3748) = 0
6114 write(1,0x8a740,13)hello RISC-V
= 13
6114 exit_group(0)
qemu での速さは CPU の性能ではない
2,000万までの素数を数える自作のプログラム(エラトステネスのふるい)を、3回ずつ動かした時間です。答え(1,270,607個、合計 12,272,577,818,052)は3つとも同じでした。
| 実行のしかた | 1回目 | 2回目 | 3回目 |
|---|---|---|---|
| x86-64(そのまま実行) | 0.167秒 | 0.185秒 | 0.156秒 |
| RISC-V(qemu-riscv64) | 0.359秒 | 0.382秒 | 0.411秒 |
| AArch64(qemu-aarch64) | 0.599秒 | 0.482秒 | 0.753秒 |
この数字は、qemu が命令を変換する手間を測ったもので、RISC-V や ARM の CPU の速さとは関係ありません。 実機の性能は、CPU の設計・クロック・メモリで決まります。qemu は「正しく動くか」「どんな命令になるか」を確かめる道具として使います。
ユーザーモード
qemu-riscv64 ./a.out。プログラム1つを動かす。この記事の方法。
OS はホストの Linux
システムモード
qemu-system-riscv64。RISC-V の仮想マシンを丸ごと動かし、Linux を起動する。
OS のイメージが要る
CPU を選ぶ
-cpu rv64,v=true,vlen=256 のように、拡張のあり・なしを切り替えられる。
次の節で使う
B拡張・V拡張を試す(Illegal instructionになる条件)
この節では、ビット操作(Zba・Zbb)とベクトル(V)の拡張で命令がどう変わるかと、CPU が拡張を持たないときに何が起きるかが分かります。
Zba・Zbb:1命令で済むようになる
__attribute__((noinline)) int bits(unsigned long x) { return __builtin_popcountl(x); }
__attribute__((noinline)) long pick(const int *a, long i) { return a[i]; }
$ riscv64-linux-gnu-gcc-13 -O3 -march=rv64gc ext.c -o ext-rv64gc
000000000000081c <bits>:
81c: 1141 addi sp,sp,-16
81e: e406 sd ra,8(sp)
820: 030000ef jal 850 <__popcountdi2>
...
000000000000082c <pick>:
82c: 058a slli a1,a1,0x2
82e: 952e add a0,a0,a1
830: 4108 lw a0,0(a0)
$ riscv64-linux-gnu-gcc-13 -O3 -march=rv64gc_zba_zbb ext.c -o ext-rv64gc_zba_zbb
000000000000081c <bits>:
81c: 60251513 cpop a0,a0
820: 8082 ret
0000000000000822 <pick>:
822: 20a5c5b3 sh2add a1,a1,a0
826: 4188 lw a0,0(a1)
1になっているビットを数える処理は、ライブラリの関数呼び出しから cpop の1命令に、配列の位置の計算(i×4+先頭)は slli+add から sh2add の1命令になりました。
CPU に拡張が無いと Illegal instruction
qemu の CPU から Zbb を外して、同じファイルを動かしました。
$ qemu-riscv64 -L $R/usr/riscv64-linux-gnu ./ext-rv64gc_zba_zbb
bits(0xF0F0)=8 pick(a,5)=5 c[63]=6363
$ qemu-riscv64 -cpu rv64,zbb=false -L $R/usr/riscv64-linux-gnu ./ext-rv64gc_zba_zbb
Illegal instruction
$ echo $?
132
コンパイルは通っても、動かす CPU がその拡張を持っていなければ、実行した瞬間に「Illegal instruction」で止まります。 -march には、動かす CPU(またはプロファイル)が持っている拡張だけを書きます。
V拡張:同じファイルが、ベクトルの長さに合わせて動く
V 拡張の組み込み関数(intrinsics)で、配列の足し算を書きました。
#include <riscv_vector.h>
/* V拡張の組み込み関数で c[i] = a[i] + b[i] を計算する */
__attribute__((noinline)) void vadd(int *c, const int *a, const int *b, size_t n) {
while (n > 0) {
size_t vl = __riscv_vsetvl_e32m1(n); /* 今回まとめて処理する要素数 */
vint32m1_t va = __riscv_vle32_v_i32m1(a, vl);
vint32m1_t vb = __riscv_vle32_v_i32m1(b, vl);
__riscv_vse32_v_i32m1(c, __riscv_vadd_vv_i32m1(va, vb, vl), vl);
a += vl; b += vl; c += vl; n -= vl;
}
}
$ riscv64-linux-gnu-gcc-13 -O2 -march=rv64gcv -mabi=lp64d vec.c -o vec
80a: 0d06f7d7 vsetvli a5,a3,e32,m1,ta,ma
812: 0205ec07 vle32.v v24,(a1)
816: 02066c87 vle32.v v25,(a2)
81c: 038c8c57 vadd.vv v24,v24,v25
820: 02056c27 vse32.v v24,(a0)
$ for v in 128 256 512; do qemu-riscv64 -cpu rv64,v=true,vlen=$v -L ... ./vec; done
vector version is not specified, use the default value v1.0
c[0]=0 c[63]=6363 vlmax(e32,m1)=4
vector version is not specified, use the default value v1.0
c[0]=0 c[63]=6363 vlmax(e32,m1)=8
vector version is not specified, use the default value v1.0
c[0]=0 c[63]=6363 vlmax(e32,m1)=16
同じ実行ファイルのまま、ベクトルレジスタの長さ(VLEN)が128・256・512ビットの CPU で、1回に処理する要素数が4・8・16個に変わり、答えは同じでした。 vsetvli が「この CPU では1回に何個できるか」を実行時に返すためです。x86 の SSE・AVX のように、レジスタの幅ごとに別の命令を書き分ける作りとは考え方が違います。
| 試したこと | 結果 |
|---|---|
-cpu rv64,v=false で vec を実行 |
Illegal instruction(終了コード132) |
-march=rv64gc で vec.c をコンパイル |
#error "Vector intrinsics require the vector extension." |
GCC 13 に --param riscv-autovec-preference=scalable |
unrecognized command-line option(GCC 13 には無い) |
GCC 13 の -O3 -march=rv64gcv で普通のループ |
ベクトル命令にならず、通常の lw・sw のループのまま |
普通の C のループを自動でベクトル命令にする機能は、手元の GCC 13.3 では働きませんでした。V 拡張を確実に使うなら、組み込み関数を書くか、より新しいコンパイラを使います。
RISC-Vの採用製品と動向(2026年10月29日時点)
この節では、RISC-V がどんな製品・OS で使われているかを、各社・各団体の公式発表で確かめた範囲で知ることができます。
RISC-V は、マイコンのような小さな CPU から、Linux が動く64ビットの CPU まで広がっています。 以下は、2026年10月29日時点で公式のページ・発表で確かめた内容だけです。
| 分野 | 内容 | 出典(公式) |
|---|---|---|
| マイコン | ESP32-C3 は最大160MHzの32ビット RISC-V のマイコンを内蔵する、Wi-Fi・Bluetooth 5(LE)対応の SoC | Espressif の製品ページ |
| マイコン | RP2350 は Arm Cortex-M33 を2つ(150MHz)と、オープンなハードウェアの Hazard3(RISC-V)を2つ持ち、どちらを使うかをソフトか OTP で選べる | Raspberry Pi の製品ページ |
| Linux | Debian 13「trixie」(2025年8月9日公開)は、初めて riscv64 を正式にサポート | Debian の公開のお知らせ |
| Linux | Ubuntu は 25.10 から RVA23 を最低限の前提にし、26.04 LTS も RVA23 を長期サポートの基準とする。RVA20 の機器は 24.04 LTS+Ubuntu Pro で最長15年のサポート | Canonical のブログ(2026年2月27日) |
| Android | RVA23 が Android の RISC-V の ABI の基準(Google の担当者の発言) | RISC-V International の RVA23 批准の発表 |
| 仕様 | ISA マニュアルの最新版は v20260120(Zalasr 拡張を追加) | docs.riscv.org |
- RISC-V のボードで新しい Ubuntu を動かすなら、ボードが RVA23 に対応しているか、RVA20(RV64GC 相当)止まりかを確かめます。
CPU が命令をどう速く実行しているか(パイプライン・分岐予測・キャッシュ)は ISA ではなく CPU の設計の話で、関連記事「CPUの気持ち8選|分岐予測・キャッシュライン・高速化」で扱っています。
RISC-Vでよくあるエラーとつまずき・誤解
この節では、RISC-V のプログラムをビルド・実行するときに出たエラーの原文と原因、よくある誤解が分かります。
| エラーの原文 | 原因 | 直し方 |
|---|---|---|
cannot execute binary file: Exec format error |
RISC-V の実行ファイルを x86 でそのまま実行した | qemu-riscv64 ./a.out で動かす |
qemu-riscv64: Could not open '/lib/ld-linux-riscv64-lp64d.so.1': No such file or directory |
RISC-V 用のローダー・ライブラリの場所を渡していない | -L /usr/riscv64-linux-gnu を付ける。または -static |
cc1: error: requested ABI requires '-march' to subsume the 'D' extension |
-march=rv64imac(D 無し)と -mabi=lp64d の組み合わせ |
D を含める(rv64gc)か、ABI を lp64 にする |
fatal error: gnu/stubs-lp64.h: No such file or directory |
Ubuntu の RISC-V 用 glibc は lp64d だけ。lp64 用が無い | Linux 向けは -mabi=lp64d を使う |
error: '-march=rv64gcx': name of non-standard extension must be more than 1 letter |
独自拡張の X の後ろに名前が無い | 拡張の名前の綴りを見直す |
Illegal instruction(終了コード132) |
CPU が持っていない拡張(Zbb・V など)の命令を実行した | -march を CPU に合わせる |
ld: cannot find …/lib/libc.so.6 |
展開しただけのツールで --sysroot を付けていない |
--sysroot=展開先 を付ける |
error while loading shared libraries: libopcodes-2.42-riscv64.so |
展開したアセンブラが共有ライブラリを見つけられない | LD_LIBRARY_PATH に展開先のライブラリを足す |
よくある誤解
「オープンだから RISC-V のチップは無料」
「何が」オープンなのかを分けて考える
「RISC-V は ARM より速い(遅い)」
比べるなら同じ条件の実機の公表値か、自分で測った値で
「RISC-V はリトルエンディアン専用」
仕様と、OS が選んだ形を分ける
「RV64 ならどれでも同じバイナリが動く」
readelf -A の Tag_RISCV_arch で確かめる
C 言語の基本(ポインタ・メモリ)が分かっていると、逆アセンブルの lw・sw が何を読み書きしているか追いやすくなります。関連記事「C言語とは|入門から環境構築・ポインタ・mallocまで実行例で解説」で扱っています。
判断表:RISC-Vを選ぶ・学ぶ場面
この節では、RISC-V を製品・開発・学習で選ぶかどうかを、場面ごとに判断できます。
| 場面 | RISC-V | 理由 |
|---|---|---|
| コンピューターの仕組み・アセンブリを学ぶ | 向く | 命令の種類が少なく、形式が揃っている。仕様書も公開されている |
| 自社の CPU・アクセラレーターを設計する | 向く | ISA の使用料が無く、独自の拡張(X〜)を足せる |
| Wi-Fi 付きのマイコンで機器を作る | 選べる | ESP32-C3 など RISC-V のマイコンが製品として出ている |
| ソフトを RISC-V の Linux でも動かす | 準備する | クロスコンパイルと qemu で確かめられる。RVA23 を前提にするか決める |
| デスクトップ・スマホのアプリ開発 | 今は主流ではない | 手元の利用者の多くは x86・ARM。RISC-V 版は追加の対応になる |
| 既存の ARM・x86 のソフト資産をそのまま使う | 向かない | 再ビルドが要り、ライブラリによっては RISC-V 版が無いこともある |
学ぶ順番の例です。
- 1C の小さな関数を書き、RISC-V 向けにコンパイルするgcc-riscv64-linux-gnu と objdump -d
- 2-M no-aliases で本当の命令を読むret・mv・li の正体を知る
- 3qemu-riscv64 で実行し、-strace で OS とのやり取りを見る静的リンクなら -L なしで動く
- 4-march を変えて、命令とサイズの変化を見るrv64g・rv64gc・_zba_zbb・v
- 5仕様書(ISA マニュアル)の RV32I の章を読む命令の形式と x0・jal・分岐の範囲
複数の CPU 向けのビルドを繰り返すときは、CC=riscv64-linux-gnu-gcc のように Makefile の変数でコンパイラを切り替えると楽です。書き方は関連記事「Makefileの書き方|自動変数一覧とタスクランナー用テンプレート」で扱っています。
よくある質問
Q. RISC-Vとは何ですか? A. CPU が理解する命令の種類と、そのビットの表し方を決めた仕様(命令セット、ISA)です。仕様は公開され、使用料なしで誰でも使えます。2010年にカリフォルニア大学バークレー校で始まり、今はスイスの非営利団体 RISC-V International が管理しています。
Q. RISC-V の読み方は? A. 「リスクファイブ」です。V はローマ数字の5です。
Q. RISC-V と ARM の違いは? A. ARM は Arm 社が持つ ISA で、使うには Arm 社との契約が入口になります。RISC-V は仕様が公開され、契約なしに使えます。命令の作りはどちらもロード・ストア型の32ビット固定長ですが、RISC-V は16ビットの圧縮命令を混ぜられ、拡張を選んで組み合わせます。手元の CoreMark では、RV64GC の .text が AArch64 より約15%小さくなりました。
Q. RISC-V のパソコンやスマホは買えますか? A. RISC-V のマイコンや、Linux が動く開発ボードは製品として出ています。新しい Ubuntu(25.10 以降)は RVA23 に対応した CPU を前提にしているため、Linux を動かすならボードの対応プロファイルを確かめます。一般向けのスマホ・パソコンでは、2026年10月29日時点で x86・ARM が主流です。
Q. RISC-V を学ぶのに実機は要りますか? A. 要りません。Ubuntu なら gcc-riscv64-linux-gnu と qemu-user で、ビルド・逆アセンブル・実行まで x86 のパソコンでできます。この記事の結果もすべて qemu で確かめました。
Q. RVA23 とは何ですか? A. 64ビットのアプリケーションプロセッサー向けに、必須の拡張をまとめたプロファイルです。2024年10月21日に批准が発表され、ベクトル(V)とハイパーバイザー(H)の拡張が必須とされています。
Q. Illegal instruction と出て止まります。
A. CPU が持っていない拡張の命令を実行しています。readelf -A の Tag_RISCV_arch でファイルが使う拡張を確かめ、-march を動かす CPU に合わせてビルドし直します。手元では、Zbb の無い CPU で cpop を実行したときと、V の無い CPU で vsetvli を実行したときに出ました。
Q. RISC-V は ARM を置き換えますか? A. この記事では予測はしません。確かめられる事実としては、Debian 13 が riscv64 を正式にサポートし、Ubuntu が RVA23 を基準に据え、Android の ABI の基準が RVA23 になった、という OS 側の対応が進んでいます。
まとめ
- RISC-V は、オープンで使用料のかからない命令セット(ISA)。CPU の製品名ではなく、仕様を RISC-V International が管理し、各社がその仕様で CPU を作る。
- ARM・x86 との一番の違いは、仕様の持ち主と使う条件。無料なのは ISA を使う権利で、コアの設計データやチップは別に費用がかかる。
- 名前は「RV64」+「I」+拡張の文字。G は IMAFD+Zicsr+Zifencei、RV64GC が Linux 向けの標準で、新しい OS は RVA23 を前提にし始めている。
- 基本の命令は32ビット固定長。手元の CoreMark では、C 拡張で命令の約54%が16ビットになり、命令の数は同じまま .text が約27%小さくなった。
- gcc-riscv64-linux-gnu と qemu-riscv64 で、x86 のパソコンでもビルド・逆アセンブル・実行まで確かめられる。CPU に無い拡張を使うと Illegal instruction になる。
参考・出典
確認日はいずれも 2026年10月29日です。
- RISC-V International「About RISC-V International」:https://riscv.org/about/
- RISC-V International「The RISC-V Instruction Set Manual」(v20260120、Introduction):https://docs.riscv.org/reference/isa/v20260120/unpriv/intro.html
- 同「RV32I Base Integer Instruction Set」:https://docs.riscv.org/reference/isa/v20260120/unpriv/rv32.html
- 同「"C" Extension for Compressed Instructions」:https://docs.riscv.org/reference/isa/v20260120/unpriv/c-st-ext.html
- 同「ISA Extension Naming Conventions」:https://docs.riscv.org/reference/isa/v20260120/unpriv/naming.html
- 同「Colophon」(版の履歴・ライセンス):https://docs.riscv.org/reference/isa/v20260120/unpriv/colophon.html
- RISC-V International「RISC-V Announces Ratification of the RVA23 Profile Standard」(2024年10月21日):https://riscv.org/blog/risc-v-announces-ratification-of-the-rva23-profile-standard/
- Arm「Licensing」:https://www.arm.com/products/licensing
- Debian「Debian 13 "trixie" released」(2025年8月9日):https://www.debian.org/News/2025/20250809
- Canonical「Canonical and Ubuntu RISC-V: a 2025 retro and looking forward to 2026」(2026年2月27日):https://ubuntu.com/blog/canonical-and-ubuntu-risc-v-a-2025-retro-and-looking-forward-to-2026
- Espressif「ESP32-C3」:https://www.espressif.com/en/products/socs/esp32-c3
- Raspberry Pi「RP2350」:https://www.raspberrypi.com/products/rp2350/
- EEMBC「CoreMark」(ソースコード):https://github.com/eembc/coremark
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「RISC-Vとは|ARM・x86との違いを逆アセンブルとqemuで実測」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。