While I’ve been skimming ARM assembly here and there, yesterday I actually had to write some from scratch to hook up seccomp on ARM. I got stumped for a while, and ended up using two references frequently:
The suffix one is pretty interesting because ARM allows for instructions to be conditional, rather than being required to rely on branching, like x86. For example, if you wanted something like this in C:
if (i == 0) i = 1; i = i + 1;
In x86 assembly, you’d have a compare followed by a jump to skip the moving of the “1” value:
cmp %ecx, $0 jne 2 mov %ecx, $1 2: inc %ecx
In ARM assembly, you can make the move conditional with a suffix (“mov if equal”):
cmp r2, #0 moveq r2, #1 add r2, r2, #1
The real thing that stumped me yesterday, though, was the “!” suffix on load/store. Mainly, I didn’t notice it was there until I’d stared at the objdump output and systematically trimmed away all other other code that wasn’t changing the behavior:
ldr r0, [sp, #OFFSET] str r0, [sp, #OFFSET]!
I was reading this as “variable = variable;” and I thought I was going crazy; how could a self-assignment change the code at all? In the second reference above, I found the that the trailing “!” means “(pre)increment the base by the offset”. I was doing a meaningless assignment, but it had the side-effect of pushing the “sp” register forward, and suddenly it all made sense (I needed to unwind the stack). The actual solution I needed was:
add sp, sp, #S_OFF
Yay for a crash-course in actual ARM assembly. :)
(And yes, I’m aware of x86’s “cmov”, but I just wanted to do a simple illustration. ARM can do conditional calls!)
© 2012, Kees Cook. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 License.