6e2f53ed80e0f48330093d0c3138e727f460ada4
explain/tinyelf-arm.md
... | ... | @@ -113,4 +113,17 @@ SECTIONS { |
113 | 113 | 00000040 61 6c 6c 40 60 00 00 00 60 00 00 00 05 49 52 43 |all@`...`....IRC| |
114 | 114 | 00000050 23 6c 73 63 01 70 a0 e3 2a 00 a0 e3 69 7a 00 ef |#lsc.p..*...iz..| |
115 | 115 | 00000060 |
116 | -``` |
|
... | ... | \ No newline at end of file |
0 | +``` |
|
1 | + |
|
2 | +## ARM sizecoding notes |
|
3 | + |
|
4 | +* All ARM instructions are 4 bytes wide |
|
5 | +* There's a "Thumb" mode, with reduced instructions (eg. no free shifts, no 3-operand instructions) where all instructions are 2 bytes wide |
|
6 | +* Switch to Thumb like this: `add lr, pc, #1; bx lr` |
|
7 | +* The `mov` opcode doesn't accept arbitrary immediate values, so you sometimes have to spill values to a "constant pool" |
|
8 | +* Null bytes decode to `andeq r0, r0` in ARM mode, or to `movs r0, r0` in Thumb mode, both are no-ops, unlike in x86 where null bytes cause a segfault. |
|
9 | + * Instruction encoding is relatively sane, so you can predict what low-value 32-bit ints will decode to so you can treat them as (almost-)no-ops. |
|
10 | +* It's a RISC, so you don't have one-byte-instructions, flexible addressing modes or stringops, but there are a few useful parts in ARM: |
|
11 | + * `pc`, `sp` etc. behave as regular registers |
|
12 | + * You can shift one operand of an instruction by a constant value for free, it doesn't cost any bytes. (ARM mode only) This can also be used to do fixed-point multiplications etc. (eg. `add r0, r0, lsr #1` for `r0*1.5`) |
|
13 | + * `ldmia`/`stmia` are great for copying stuff around. |
|
... | ... | \ No newline at end of file |