Useful objasm macros |
; EQUB <value> ; set a byte MACRO EQUB $var DCB $var MEND
; EQUW <value> ; Set a 16 bit value MACRO EQUW $var DCW $var MEND
; EQUD <value> ; Set a 32 bit value MACRO EQUD $var DCD $var MEND
; EQUS "<value>" ; Set a string. ; For 'EQUS "something", 13, 0' ; you will need use DCB directly. MACRO EQUS $var DCB "$var" MEND
; EQUSZ "<value>" ; Set a string and zero-terminate it. MACRO EQUSZ $var DCB "$var", 0 MEND
; EQUSB "<value>" ; Set a string and BASIC-style terminate it. MACRO EQUSZ $var DCB "$var", 13 MEND
; EQUSZA "<value>" ; Set a string and zero-terminate it, then align. MACRO EQUSZA $var DCB "$var", 0 ALIGN MEND
stm_temp RLIST {R0-R3,R14} ldm_temp RLIST {R0-R3,PC} str_temp RLIST {R0-R3}Then, in your code, instead of:
STMFD R13!, {R0-R3, R14}
...
LDMFD R13!, {R0-R3, PC}
STMFD R13!, stm_temp
...
LDMFD R13!, ldm_temp
The 'str_temp' version is for when you want to store/load without messing with R14/PC. The same is used for both loading and storing.
; BSR "<function>" ; Branch to subroutine saving R14 around it ; This is a lot like JSR on the 6502. MACRO $label BSR $dest $label PushLR BL $dest PullLR MEND
; Pull "<reglist>" [,<"condition"> [,"^"]] ; Pull registers given in reglist. Can be conditional. ; Use '^' with care. ; Example: ; Pull "R2-R4", "EQ" MACRO $label Pull $reglist, $cond, $hat $label LDM$cond.FD R13!, {$reglist}$hat MEND
; Push "<reglist>" [,<"condition">] ; Push registers given in reglist. Can be conditional. ; Example: ; Push "R2-R4", "EQ" MACRO $label Push $reglist, $cond $label STM$cond.FD R13!, {$reglist} MEND
; Push LR (and only LR) to the stack. ; Optimised for fast saving of one register, ; instead of using STMFD R13!, {LR} ; Can be conditional. MACRO $label PushLR $cond $label STR$cond. R14, [R13, #-4]! MEND
; Pull LR (and only LR) from the stack. ; Optimised form of LDMFD R13!, {LR} ; Can be conditional. MACRO $label PullLR $cond $label LDR$cond. R14, [R13], #4 MEND
; Return from function. ; Can be conditional. DOES NOT RESTORE FLAGS. MACRO $label Ret $cond $label MOV$cond PC, R14 MEND ; This is functionally the same as 'Ret'. Use ; whichever you prefer. MACRO $label Return $cond $label MOV$cond PC, R14 MEND
; Pull LR and Return ; This is equivalent to: ; PullLR ; Return ; but it saves an instruction as we load to PC MACRO $label PullRet $cond $label LDR$cond. PC, [R13], #4 MEND
; SetV sets the oVerflow flag ; regardless of processor type MACRO $label SetV ; DOES NOT TAKE A CONDITION $label CMP R0, #1<<31 CMNVC R0, #1<<31 MEND
; ProcMode returns: ; EQ if 32 bit (PC and CPSR) mode ; NE if 26 bit (PC + PSR) mode MACRO $label ProcMode ; DOES NOT TAKE A CONDITION $label TEQ PC, #0 TEQ PC, PC MEND
Sometimes it can be useful to stick in an on-screen debugging message so you can quickly trace the flow of the program without restorting to the tedium of single-stepping in the debugger...
; DebugMsg - embeds a debugging message MACRO DebugMsg $msg SWI XOS_WriteS DCB "$msg", 13, 10, 0 ALIGN MENDYou could expand upon this by, for instance, wrapping it in a conditional test for a DEBUG 'define'. In this way, you can simply alter the DEBUG 'define' to make the macro either output the in-line debugging string or simply do nothing.