arm64_01
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* ARM64の勉強#1
-(by [[K]], 2020.08.23)
** (0)
-格安スマホや適当なAndroidタブレットに、Termuxをインスト...
** (1)
#include <stdio.h>
#include <stdint.h>
int main()
{
printf("%d\n", (int) sizeof (int32_t));
return 0;}
}
-4が表示されました。よしよし。
** (2)
#include <stdio.h>
#include <stdint.h>
uint32_t t[] = { 0xd2800000 | 123 << 5, 0xd65f03c0 }; //...
int main()
{
int (*fnc)() = (int (*)()) t;
int i = fnc();
printf("i=%d\n", i);
return 0;
}
-実行したら、「Segmentation fault」になってしまいました。...
-上記の機械語については以下を参照しました。
--x0レジスタに関数の戻り値を設定すればよさそうだというこ...
https://docs.microsoft.com/ja-jp/cpp/build/arm64-windows-...
の「戻り値」のところを見ました。これはARM64-Linuxではなく...
--x0への代入の機械語は、
https://www.mztn.org/dragon/arm6405str.html#mov
の「MOVZ」のところを参考にしました。
--retの機械語は、
https://www.mztn.org/dragon/arm6408cond.html#ret
の「RET」のところを参考にしました。
** (3)
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 8, PROT_READ | PROT_WRITE | ...
code[0] = 0xd2800000 | 123 << 5; // x0=123;
code[1] = 0xd65f03c0; // ret;
int i = ((int (*)()) code)();
printf("i=%d\n", i);
return 0;
}
-実行したら、「i=123」と表示されました。大成功です!
** (4)
//-todo: putcharではなく、myPutcharにしたほうがよさそう。...
//-nopはd503201f
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 36, PROT_READ | PROT_WRITE |...
code[0] = 0xa9800000 | 30 | 19 << 10 | 31 << 5 | ((-...
code[1] = 0xaa000000 | 1 << 16 | 31 << 10 | 19; // x...
code[2] = 0xd2800000 | 'A' << 5; // x0='A';
code[3] = 0xd63f0000 | 19 << 5; // BLR x19;
code[4] = 0xd2800000 | '\n' << 5; // x0='\n';
code[5] = 0xd63f0000 | 19 << 5; // BLR x19;
code[6] = 0xa8c00000 | 30 | 19 << 10 | 31 << 5 | ((+...
code[7] = 0xd2800000 | 123 << 5; // x0=123;
code[8] = 0xd65f03c0; // ret;
printf("%x\n", code[0]); // この行をなくすとセグメン...
int i = ((int (*)(void *)) code)(putchar);
printf("i=%d\n", i);
return 0;
}
-code上のプログラムはなぜかx1で引数を受けなければいけない...
-なんかclangが作ったバイナリを見ていると、呼び出し処理の...
-clangが悪いのではなく、私のプログラムが悪いのかもしれな...
--(註)後日自分のミスだとわかりました。(4)のつづきを参照。
-もっと本番のJITに近い方法で関数ポインタを渡してみて、そ...
----
-いろいろ苦戦したメモ
-最初のバージョンはセグメントフォールトで失敗。
-試行錯誤したところ、関数呼び出しさえしなければなんとか完...
-いろいろ確認したところ、どうもハンドアセンブルは間違って...
-https://qiita.com/hotpepsi/items/bd1f496411a2df74b704 を...
-ということでx0は使わないでx1からにしてみたら、セグメント...
-x0で渡せばちゃんと表示されることが分かった。
** (5)
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
void *vp[4]; vp[0] = putchar;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 36, PROT_READ | PROT_WRITE |...
code[0] = 0xa9800000 | 30 | 19 << 10 | 31 << 5 | ((-...
code[1] = 0xf9400000 | 0 << 10 | 0 << 5 | 19; // x19...
code[2] = 0xd2800000 | 'A' << 5; // x0='A';
code[3] = 0xd63f0000 | 19 << 5; // BLR x19;
code[4] = 0xd2800000 | '\n' << 5; // x0='\n';
code[5] = 0xd63f0000 | 19 << 5; // BLR x19;
code[6] = 0xa8c00000 | 30 | 19 << 10 | 31 << 5 | ((+...
code[7] = 0xd2800000 | 123 << 5; // x0=123;
code[8] = 0xd65f03c0; // ret;
int i = ((int (*)(void **)) code)(vp);
printf("i=%d\n", i);
return 0;
}
-これで期待通りに素直に動くことが分かった。たぶん関数ポイ...
** (6)
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
void *vp[4]; vp[0] = putchar;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 60, PROT_READ | PROT_WRITE |...
code[ 0] = 0xa9800000 | 31 << 5 | ((-16/8)&127) << 1...
code[ 1] = 0xa9800000 | 31 << 5 | ((-16/8)&127) << 1...
code[ 2] = 0xf9400000 | 19 | 0 << 5 | 0 << 10; ...
code[ 3] = 0xd2800000 | 20 | 0x20 << 5; ...
code[ 4] = 0xaa000000 | 31 << 16 | 0 | 20 << 5; ...
code[ 5] = 0xd63f0000 | 19 << 5; ...
code[ 6] = 0x91000000 | 20 | 20 << 5 | 1 <<10; ...
code[ 7] = 0xf1000000 | 31 | 20 << 5 | 0x7f << 10; ...
code[ 8] = 0x54000000 | 0x01 | ((-4)&524287) << 5; ...
code[ 9] = 0xd2800000 | 0 | 0xa << 5; ...
code[10] = 0xd63f0000 | 19 << 5; ...
code[11] = 0xa8c00000 | 31 << 5 | (+16/8)&127) << 15...
code[12] = 0xa8c00000 | 31 << 5 | (+16/8)&127) << 15...
code[13] = 0xd2800000 | 0 | 123 << 5; ...
code[14] = 0xd65f03c0; ...
int i = ((int (*)(void **)) code)(vp);
printf("i=%d\n", i);
return 0;
}
-これで「 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO...
-成功!
** (4)のつづき
code[1] = 0xaa000000 | 1 << 16 | 31 << 10 | 19; // x...
-これは機械語が変だぞ。なんかいじっているうちにおかしくな...
-っていうか、それだからうまくいかなかっただけなんじゃない...
-ということで直してやり直してみる。
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 36, PROT_READ | PROT_WRITE |...
code[0] = 0xa9800000 | 30 | 19 << 10 | 31 << 5 | ((-...
code[1] = 0xaa000000 | 31 << 16 | 19 | 0 << 5; // x1...
code[2] = 0xd2800000 | 'A' << 5; // x0='A';
code[3] = 0xd63f0000 | 19 << 5; // BLR x19;
code[4] = 0xd2800000 | '\n' << 5; // x0='\n';
code[5] = 0xd63f0000 | 19 << 5; // BLR x19;
code[6] = 0xa8c00000 | 30 | 19 << 10 | 31 << 5 | ((+...
code[7] = 0xd2800000 | 123 << 5; // x0=123;
code[8] = 0xd65f03c0; // ret;
int i = ((int (*)(void *)) code)(putchar);
printf("i=%d\n", i);
return 0;
}
-うまくいった!
** (9)
-ここまでのまとめ
|MOVZ|0xd2800000 + imm16 << 5 + reg|(2)|x0~x30にimm16を...
|RET|0xd65f03c0|(2)|PC=x30|
|MOV|0xaa000000+31<<10 + src << 16 + dst|(4)|dst=src|
|push|0xa9800000+31<<5+((-16/8)&127)<<15 + reg0 + reg1 <<...
|pop |0xa8c00000+31<<5+((+16/8)&127)<<15 + reg0 + reg1 <<...
|BLR |0xd63f0000 + reg << 5|(4)|レジスタで指定する関数呼...
|NOP |0xd503201f||NOP|
|LDR |0xf9400000 + disp/8 << 10 + base << 5 + dst|(5)|メ...
* こめんと欄
#comment
終了行:
* ARM64の勉強#1
-(by [[K]], 2020.08.23)
** (0)
-格安スマホや適当なAndroidタブレットに、Termuxをインスト...
** (1)
#include <stdio.h>
#include <stdint.h>
int main()
{
printf("%d\n", (int) sizeof (int32_t));
return 0;}
}
-4が表示されました。よしよし。
** (2)
#include <stdio.h>
#include <stdint.h>
uint32_t t[] = { 0xd2800000 | 123 << 5, 0xd65f03c0 }; //...
int main()
{
int (*fnc)() = (int (*)()) t;
int i = fnc();
printf("i=%d\n", i);
return 0;
}
-実行したら、「Segmentation fault」になってしまいました。...
-上記の機械語については以下を参照しました。
--x0レジスタに関数の戻り値を設定すればよさそうだというこ...
https://docs.microsoft.com/ja-jp/cpp/build/arm64-windows-...
の「戻り値」のところを見ました。これはARM64-Linuxではなく...
--x0への代入の機械語は、
https://www.mztn.org/dragon/arm6405str.html#mov
の「MOVZ」のところを参考にしました。
--retの機械語は、
https://www.mztn.org/dragon/arm6408cond.html#ret
の「RET」のところを参考にしました。
** (3)
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 8, PROT_READ | PROT_WRITE | ...
code[0] = 0xd2800000 | 123 << 5; // x0=123;
code[1] = 0xd65f03c0; // ret;
int i = ((int (*)()) code)();
printf("i=%d\n", i);
return 0;
}
-実行したら、「i=123」と表示されました。大成功です!
** (4)
//-todo: putcharではなく、myPutcharにしたほうがよさそう。...
//-nopはd503201f
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 36, PROT_READ | PROT_WRITE |...
code[0] = 0xa9800000 | 30 | 19 << 10 | 31 << 5 | ((-...
code[1] = 0xaa000000 | 1 << 16 | 31 << 10 | 19; // x...
code[2] = 0xd2800000 | 'A' << 5; // x0='A';
code[3] = 0xd63f0000 | 19 << 5; // BLR x19;
code[4] = 0xd2800000 | '\n' << 5; // x0='\n';
code[5] = 0xd63f0000 | 19 << 5; // BLR x19;
code[6] = 0xa8c00000 | 30 | 19 << 10 | 31 << 5 | ((+...
code[7] = 0xd2800000 | 123 << 5; // x0=123;
code[8] = 0xd65f03c0; // ret;
printf("%x\n", code[0]); // この行をなくすとセグメン...
int i = ((int (*)(void *)) code)(putchar);
printf("i=%d\n", i);
return 0;
}
-code上のプログラムはなぜかx1で引数を受けなければいけない...
-なんかclangが作ったバイナリを見ていると、呼び出し処理の...
-clangが悪いのではなく、私のプログラムが悪いのかもしれな...
--(註)後日自分のミスだとわかりました。(4)のつづきを参照。
-もっと本番のJITに近い方法で関数ポインタを渡してみて、そ...
----
-いろいろ苦戦したメモ
-最初のバージョンはセグメントフォールトで失敗。
-試行錯誤したところ、関数呼び出しさえしなければなんとか完...
-いろいろ確認したところ、どうもハンドアセンブルは間違って...
-https://qiita.com/hotpepsi/items/bd1f496411a2df74b704 を...
-ということでx0は使わないでx1からにしてみたら、セグメント...
-x0で渡せばちゃんと表示されることが分かった。
** (5)
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
void *vp[4]; vp[0] = putchar;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 36, PROT_READ | PROT_WRITE |...
code[0] = 0xa9800000 | 30 | 19 << 10 | 31 << 5 | ((-...
code[1] = 0xf9400000 | 0 << 10 | 0 << 5 | 19; // x19...
code[2] = 0xd2800000 | 'A' << 5; // x0='A';
code[3] = 0xd63f0000 | 19 << 5; // BLR x19;
code[4] = 0xd2800000 | '\n' << 5; // x0='\n';
code[5] = 0xd63f0000 | 19 << 5; // BLR x19;
code[6] = 0xa8c00000 | 30 | 19 << 10 | 31 << 5 | ((+...
code[7] = 0xd2800000 | 123 << 5; // x0=123;
code[8] = 0xd65f03c0; // ret;
int i = ((int (*)(void **)) code)(vp);
printf("i=%d\n", i);
return 0;
}
-これで期待通りに素直に動くことが分かった。たぶん関数ポイ...
** (6)
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
void *vp[4]; vp[0] = putchar;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 60, PROT_READ | PROT_WRITE |...
code[ 0] = 0xa9800000 | 31 << 5 | ((-16/8)&127) << 1...
code[ 1] = 0xa9800000 | 31 << 5 | ((-16/8)&127) << 1...
code[ 2] = 0xf9400000 | 19 | 0 << 5 | 0 << 10; ...
code[ 3] = 0xd2800000 | 20 | 0x20 << 5; ...
code[ 4] = 0xaa000000 | 31 << 16 | 0 | 20 << 5; ...
code[ 5] = 0xd63f0000 | 19 << 5; ...
code[ 6] = 0x91000000 | 20 | 20 << 5 | 1 <<10; ...
code[ 7] = 0xf1000000 | 31 | 20 << 5 | 0x7f << 10; ...
code[ 8] = 0x54000000 | 0x01 | ((-4)&524287) << 5; ...
code[ 9] = 0xd2800000 | 0 | 0xa << 5; ...
code[10] = 0xd63f0000 | 19 << 5; ...
code[11] = 0xa8c00000 | 31 << 5 | (+16/8)&127) << 15...
code[12] = 0xa8c00000 | 31 << 5 | (+16/8)&127) << 15...
code[13] = 0xd2800000 | 0 | 123 << 5; ...
code[14] = 0xd65f03c0; ...
int i = ((int (*)(void **)) code)(vp);
printf("i=%d\n", i);
return 0;
}
-これで「 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO...
-成功!
** (4)のつづき
code[1] = 0xaa000000 | 1 << 16 | 31 << 10 | 19; // x...
-これは機械語が変だぞ。なんかいじっているうちにおかしくな...
-っていうか、それだからうまくいかなかっただけなんじゃない...
-ということで直してやり直してみる。
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t *code;
posix_memalign((void **) &code, sysconf(_SC_PAGESIZE...
mprotect((void *) code, 36, PROT_READ | PROT_WRITE |...
code[0] = 0xa9800000 | 30 | 19 << 10 | 31 << 5 | ((-...
code[1] = 0xaa000000 | 31 << 16 | 19 | 0 << 5; // x1...
code[2] = 0xd2800000 | 'A' << 5; // x0='A';
code[3] = 0xd63f0000 | 19 << 5; // BLR x19;
code[4] = 0xd2800000 | '\n' << 5; // x0='\n';
code[5] = 0xd63f0000 | 19 << 5; // BLR x19;
code[6] = 0xa8c00000 | 30 | 19 << 10 | 31 << 5 | ((+...
code[7] = 0xd2800000 | 123 << 5; // x0=123;
code[8] = 0xd65f03c0; // ret;
int i = ((int (*)(void *)) code)(putchar);
printf("i=%d\n", i);
return 0;
}
-うまくいった!
** (9)
-ここまでのまとめ
|MOVZ|0xd2800000 + imm16 << 5 + reg|(2)|x0~x30にimm16を...
|RET|0xd65f03c0|(2)|PC=x30|
|MOV|0xaa000000+31<<10 + src << 16 + dst|(4)|dst=src|
|push|0xa9800000+31<<5+((-16/8)&127)<<15 + reg0 + reg1 <<...
|pop |0xa8c00000+31<<5+((+16/8)&127)<<15 + reg0 + reg1 <<...
|BLR |0xd63f0000 + reg << 5|(4)|レジスタで指定する関数呼...
|NOP |0xd503201f||NOP|
|LDR |0xf9400000 + disp/8 << 10 + base << 5 + dst|(5)|メ...
* こめんと欄
#comment
ページ名: