summaryrefslogtreecommitdiff
path: root/log.md
diff options
context:
space:
mode:
authorCamil Staps2016-09-19 23:43:29 +0200
committerCamil Staps2016-09-19 23:43:29 +0200
commit7f44d782ed2cd60bae59a7aa73e467d2299fb293 (patch)
tree3d9b3cb2dd78740441a79a77a62e28d1c59fc746 /log.md
parentLog 09-19 (diff)
Log 9-19 (first working program, yay)
Diffstat (limited to 'log.md')
-rw-r--r--log.md43
1 files changed, 43 insertions, 0 deletions
diff --git a/log.md b/log.md
index 7083d30..c96d8e5 100644
--- a/log.md
+++ b/log.md
@@ -34,3 +34,46 @@ Talked to John:
- When the program counter is stored on the stack in ARM (`str pc,[sp,#-4]!`),
the value pushed is actually the PC + 8, which gives space for a call after
storing the PC. On Thumb-2 this is different, so this should be checked.
+
+To solve the latter problem, we need to add an offset to the stored PC. Old ARM
+code was:
+
+```armasm
+str pc,[sp,#-4]! @ Actually pushed PC+8, to after the branch.
+```
+
+First solution, since `PC` cannot be `Rd` for `str`:
+
+```armasm
+mov r12,pc @ Stores PC+4 (see A5.1.2 of the ARMv7-A manual) (this is a 16-bit instruction)
+str r12,[sp,#-4]! @ Pushes stored value (address of THIS register)
+```
+
+New solution, with a proper offset:
+
+```armasm
+add r12,pc,#9 @ Stores PC+12+1 (this is a 32-bit instruction)
+ @ +1; bit 0 is the execution state and should be Thumb-2
+str r12,[sp,#-4]! @ This is a 32-bit instruction, as is the branch below
+```
+
+After this, this program crashes only when it wants to print time information
+(specifically, `time_string_4`, `thumb2startup.s:929`):
+
+```clean
+Start = 10
+```
+
+The last crash has to do with alignment in `exit_clean` (`thumb2startup.s`).
+This indicates that `add r12,pc,#9` is not right in some cases. The second
+bullet point in A5.1.2 applies:
+
+> Read the word-aligned PC value, that is, the address of the current
+> instruction + 4, with bits [1:0] forced to zero.
+
+Hence, in some cases (when the address of the `add` instruction is 2 mod 4), we
+should add 11 instead of 9. A quick fix is to use `.align`, which inserts a
+`nop` if needed. It would be more convenient if there would be preprocessor
+directives like `.align` where you could yourself decide what is added
+depending on the current alignment (see
+http://stackoverflow.com/q/39582517/1544337 for this).