Anyway, thank you, OP, for sharing this. I have been looking into picking up ARM as way to crawl out of burnout from my career. It's been a years since I even touched x86 with any seriousness. I will add this book to my list resources.
The linked document is an old one, current ones are at https://riscv.org/technical/specifications/
The machine had a much more complete assembly language programming toolkit which I also used to write more sophisticated programs, employing this debugger to examine them. But I felt like I'd "cracked the code" of the computer when I plugged hex numbers into RAM and then ran them straight from there.
Most CPU ISA documentation should give you the opcodes that correspond to instruction mnemonics. You may have to plug in your own operands (registers, etc.) into bit fields in the instruction encoding. If you're serious about hand-assembling to begin with this should be no problem.
Start at section A5 describing the encoding. The instruction set is very much designed for clean decode, so instructions are grouped by bit pattern; every instruction in the manual has its bit pattern described.
Very much a "but why?" situation, since translation from assembly to machine code is so easily automatable and doing it by hand adds so little value.
Agreed. More of a curiosity for me from learning and research purposes.
Me too; that's also the reason why I wanted that possibility back.
I'd be happy to support you if you choose to try it out! Ask as many questions as you like.
Even if you choose not to, you might like the cheatsheet in the repo (from https://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x8...)
And that cheat sheet PDF is cool, exactly what I was looking for. Any chance you are aware of something similar for x64? Thanks.
older official arm documentation is a lot better than recent, which is very poor quality (though still pretty reliable.) oldnewthing and azeria-labs have good tutorials, though she got some of the condition flags wrong
I have also never again reached the high water mark of my programming life, which happened in that class - entering a 10-second ascended state and writing a 60-line complex assembly function in one go, no backspaces, no changes, and it working perfectly.
addem: xor eax, eax
loop:
test ecx, ecx
jnz ok
ret
ok: add eax, [ebx + ecx * 4]
dec ecx
jmp loop
(i haven't tested this, it'd be hilarious if i got it wrong)So, like if you passed a wrong value to a certain register, then downstream, every problem that used that register would be off.
The tests were often 4 pages front and back with the handwritten assembly, definition matching, word problems, essay responses, etc.. We had like 75 minutes to take the test too. This was all at a public, no-name state university too. I was no MIT student or anything.
Anyway, I'll never forget the first day of class. Our professor said we were to have 4 tests and a final and some labs.
My friend in the class: "If we make a 100 on all 4 tests, do we have to take the final?"
The professor: "Hell, if you make 100 on 4 test, then I will let you write the final."
My friend: "Why? Has no one ever done that before?"
Professor: "No, in fact, in the 20 years I have taught this class, no one has ever scored a 100 on any test."
We all knew we were in for hell after that.
[1]: https://en.wikipedia.org/wiki/Scratch_(programming_language)
push {ip, lr}
ldr r0, =hello
bl printf
mov r0, #41
add r0, r0, #1 // Increment
pop {ip, lr}
bx lr
str r0, [r1] /* M[r1] = r0; */
ldr r0, [r1] /* r0 = M[r1]; */
str r0, [r1, #8] /* M[r1 + 8] = r0; */
ldr r0, [r1, #8] /* r0 = M[r1 + 8]; */
str r0, [r1, -r2] /* M[r1 - r2] = r0; */
ldr r0, [r1, -r2] /* r0 = M[r1 - r2]; */
with the destination on the left-hand side, with no "%" before the register names, and with the square brackets for addresses (with relatively sane looking expressions inside those brackets) — basically the same syntax that ARM's own assembler uses, — while x86 gets some absolutely unhinged syntax that looks like it just fell out of the sky (or an abyss for that matter) since it has almost no relation to what's written in the Intel's docs? I always assumed that GAS used some "unified" style for all its targets and disregarded the conventions of the CPU manufacturers but apparently no, it only did that for x86?There's also legacy ARMASM syntax that is barely worth mentioning.
Arm can get a bit gnarly too. that bx lr is attempting to switch between arm32 and thumb based on the MSB of 'ip' based on the pop prior. the 'str' is moving data from left to right, but the ldr is moving data from right to left. you also end up doing weird and cumbersome things sometimes because of the instruction width limitations. I think arm64 looks and is much nicer than arm32 and thumb.
btw try
.intel_syntax noprefixAnyhow, so I’ve got a bunch of .bin files around for it, no C source code, just straight assembly output ready to be flashed. And the text and data segments are often interwoven, each fetch being resolved to data or instruction in real time by the rabbit processor. So I’ve been thinking of sitting down, going through the assembly/processor manual for the board and just writing a board simulator hoping to get it back to source code by blackbox reversing in a sense. I’d have to rummage through JEDEC for the standard used by the EEPROM to figure out what pins it’s using there and the edge triggering sequences. Once I can execute it and see what registers and GPIOs are written when, I can probably figure out the original code path. Not sure if anyone has tips or guides or suggestions here.
So I don’t know if it would be easier trying to find this, and updating it to support rabbit, vs trying to wedge something into ghidra which itself is an undertaking of a behemoth platform. As far as I know ghidra does not have Z80 support.
Though Why use 32bit instead of 64, why add so much friction for a first time learner.
ARM32 is a gem, in my opinion. A truly simple instruction set, and easy to get your hands on with Raspberry Pi or emulation.
In any case, I find it interesting to write a compiler and do want to continue with this book, so perhaps I'll just write the code on my MacBook and then transfer it to my Windows gaming PC to run it on WSL or something :)