ARM64の勉強#1
(0)
- 格安スマホや適当なAndroidタブレットに、Termuxをインストールして、clangを使っていろいろ実験しました。ソースコードはnanoで入力しています。
(1)
#include <stdio.h>
#include <stdint.h>
int main()
{
printf("%d\n", (int) sizeof (int32_t));
return 0;}
}
(2)
#include <stdio.h>
#include <stdint.h>
uint32_t t[] = { 0xd2800000 | 123 << 5, 0xd65f03c0 }; // x0=123; ret;
int main()
{
int (*fnc)() = (int (*)()) t;
int i = fnc();
printf("i=%d\n", i);
return 0;
}
- 実行したら、「Segmentation fault」になってしまいました。まあ当然か・・・。
(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), 8);
mprotect((void *) code, 8, PROT_READ | PROT_WRITE | PROT_EXEC);
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), 36);
mprotect((void *) code, 36, PROT_READ | PROT_WRITE | PROT_EXEC);
code[0] = 0xa9800000 | 30 | 19 << 10 | 31 << 5 | ((-16/8)&127) << 15; // x19, x30 をpush.
code[1] = 0xaa000000 | 0 << 16 | 31 << 10 | 19; // ORR x19,xzr,x0 (MOV)
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 | ((+16/8)&127) << 15; // x19, x30 をpop.
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 << 10 | (4) | レジスタペアのストア |
| pop | 0xa8c00000+31<<5+((+16/8)&127)<<15 + reg0 + reg1 << 10 | (4) | レジスタペアのロード |
| BLR | 0xd63f0000 + reg << 5 | (4) | レジスタで指定する関数呼び出し |
こめんと欄