asm.md 6.52 KB
 Aaron Erhardt committed May 06, 2021 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 ``````# Assembler ## Arithmetic ### Add ```asm add r0, r1, r2 ; ro = r1 + r2 add r0, r1 ; ro = r0 + r1 add r0, #1 ; ro = r0 + 1, for small constants ``` Set flags while adding ```asm adds r0, r1, r2 ; ro = r1 + r2, also sets flags ``` ### Subtract ```asm sub r0, r1, r2 ; ro = r1 - r2 ``` ### Multiply ```asm mul r0, r1, r2 ; ro = r1 * r2 ``` ### Divide ```asm udiv r0, r1, r2 ; ro = r1 / r2, unsigned divide, always rounds down ``` ## Logic ### And ```asm and r0, r1, r2 ; ro = r1 AND r2 ``` ### OR ```asm orr r0, r1, r2 ; ro = r1 OR r2 ``` ### Exclusive or ```asm eor r0, r1, r2 ; ro = r1 XOR r2 ``` ## Shift ### Arithmetic shift right ```asm asr r0, r1, r2 ; ro = r1 >> r2, keeps correct sign! ``` ### Logical shift right ```asm lsr r0, r1, r2 ; ro = r1 >> r2, fills with zeros and doesn't keep correct sign! ``` ### Logical shift left ```asm lsl r0, r1, r2 ; ro = r1 << r2, fills with zeros ``` ### Rotate right ```asm ror r0, r1, r2 ; ro = r1 >> r2, bits will wrap around ``` `````` Aaron Erhardt committed Apr 15, 2021 84 85 86 ``````## Load ```asm `````` Aaron Erhardt committed Apr 29, 2021 87 ``````ldr rd, =const ; load constant `````` Aaron Erhardt committed Apr 15, 2021 88 89 90 91 92 93 94 95 96 97 98 99 100 ``````ldr r1, [r0] ; load content of address of r0 into r1 ldr r1, [r0, #8] ; same with offset ldr r1, [r0], #8 ; post-increment ldr r1, [r0, #8]! ; pre-increment ``` Load value defined by dcd ```asm MAX DCD 10 ldr r3, MAX ``` `````` Aaron Erhardt committed May 06, 2021 101 ``````### Store `````` Aaron Erhardt committed Apr 15, 2021 102 103 `````` ```asm `````` Aaron Erhardt committed May 06, 2021 104 105 106 107 ``````str r1, [r0] ; store content of r1 into address of r0 str r1, [r0, #8] ; same with offset str r1, [r0], #8 ; post-increment str r1, [r0, #8]! ; pre-increment `````` Aaron Erhardt committed Apr 15, 2021 108 109 ````````` `````` Aaron Erhardt committed May 06, 2021 110 ``````## Move `````` Aaron Erhardt committed Apr 15, 2021 111 112 `````` ```asm `````` Aaron Erhardt committed May 06, 2021 113 114 ``````mov r0, r1 ; r0 := r1 mov rd, #const ; const max. 16-Bit, otherwise load `````` Aaron Erhardt committed Apr 15, 2021 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ````````` ## Compare ```asm ; like subtraction, but only sets flags cmp r0, r1 ; zero flag set if equal, etc. cmp r0, 0 ; compare with constant ``` ## Branch Unconditional branch ```asm b LABEL ; jump to label ``` Compare binary numbers ```asm ; use "cmp r1 r2" always before branch ; COMMAND ; meaning C-Code Flags beq LABEL ; equal r1 == r2 Z = 1 bne LABEL ; not equal r1 != r2 Z = 0 bgt LABEL ; greater r1 > r2 N = 0 bge LABEL ; greater equal r1 => r2 N = 0 or Z = 1 blt LABEL ; lower r1 < r2 N = 1 ble LABEL ; lower equal r1 =< r2 N = 1 or Z = 1 ``` Branch with flag values ```asm ; COMMAND ; meaning Flags bcs LABEL ; carry set C = 1 bcc LABEL ; carry cleared C = 0 bmi LABEL ; minus N = 1 bpl LABEL ; plus N = 0 bvs LABEL ; overflow set V = 1 bvc LABEL ; overflow cleared V = 0 beq LABEL ; equal Z = 1 bne LABEL ; not equal Z = 0 ``` `````` Aaron Erhardt committed Apr 22, 2021 160 161 162 ``````## Stack ```asm `````` Aaron Erhardt committed Apr 29, 2021 163 164 ``````push {r1} ; push r1 on the stack pop {r1} ; restore r1 from the stack `````` Aaron Erhardt committed Apr 22, 2021 165 166 167 168 169 170 `````` push {r0-r5} ; push r0-r5 pop {r0-r5} ; pop r0-r5 (in the correct order) push {lr, r3, r10-12} ; push lr, r3 and r10-r12 pop {lr, r3, r10-12} ; pop lr, r3 and r10-r12 `````` Aaron Erhardt committed Apr 29, 2021 171 172 ````````` `````` Aaron Erhardt committed May 06, 2021 173 ``````## Subroutines `````` Aaron Erhardt committed Apr 29, 2021 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 `````` ```asm main bl label ; run subroutine label ; push all registers the subroutine changes except returned registers push {lr, ...} ; ... ; other code pop {lr, ...} ; pop the registers again bx lr ; jump back ``` ## Pass parameters ### Register ```asm main ldr r0, =1 ; initialize parameters ldr r1, =2 bl add_nums ; run subroutine ; r2 can now be used as returned value add_nums push {lr} add r2, r0, r1 ; add r0 and r1 and return value at r2 pop {lr} bx lr ``` ### Stack ```asm main ldr r7, =1 ; initialize parameters ldr r8, =2 ; prepare parameters and return values push {r7} ; parameter 1 push {r8} ; parameter 2 push {r9} ; return value 1 bl add_nums ; run subroutine pop {r9} ; get return value from the stack pop {r8} ; free stack space again pop {r7} ; free stack space again add_nums push {lr, r0-r2} ; increments stack pointer by 4 * (amount of registers)! ; load parameters into registers ldr r0, [sp, #4*6] ; 4*4 + 4*2 -> r7 (was pushed first, highest address) ldr r1, [sp, #4*5] ; 4*4 + 4*1 -> r8 add r2, r0, r1 ; perform actual calculation ; store return values on reserved the stack space str r2, [sp, #4*4] ; 4*4 + 4*0 -> r9 pop {lr, r0-r2} bx lr ``` `````` Aaron Erhardt committed May 06, 2021 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 `````` # IO IO is memory mapped, it is read and set just like a block of memory. ## Typical register types + Control register (set behavior) + Status register + Data register ## STM32 ### RCC (Reset and Control Logic) Used to explicitly turn on other I/O blocks by setting bits in the registers. ### GPIO (General Purpose I/O) Configuration: + Set RCC bits to enable I/O block + Set pins as input, output, alternate function (reserve pin for other I/O blocks) or analog with two bits in the MODER register + Adjust edge steepness (Flankensteilheit) with two bits in the OSPEEDR register + Set pull up resistance to NONE, UP or DOWN with two bits in the PUPDR register Output: Set bits of the ODR register to activate individual pins Input: Read bits of the IDR register to get values of individual pin **Example** ```asm ; define port addresses and register offsets (data sheet)... InitOutputPortB push {r0, r3, r4, lr} ; Enable I/O block for PortB ldr r3, = RCC ; Load start address of RCC registers into r3 ldr r0, [r3, #AHB1ENR] ; Load current register values orr r0, r0, #IOPBEN ; Use logical OR to enable the bit for GPIOBEN and leave the rest unchanged str r0, [r3, #AHB1ENR] ; Store value into the register to enable I/O on PortB ; Configure PortB ldr r3, = GPIOB ; Load start address of GPIOB registers into r3 ldr r0, = 0x00005555 ; Load values for configuring the MODER register, using 0x5 = 01_01 to set all pins as output str r0, [r3, #MODER] ; Store value into the register to enable configuration ; Turn on LEDs ldr r0, #3 ; Set first to bits str r0, [r3, #ODR] ; Load value into ODR register to enable the first to outputs (LEDs) pop {r0, r3, r4, lr} ``` ### Systick timer Counts down from a start value until it reaches zero. Then is sets a flag, invokes an interrupt, resets the start value and counts down again. STK_CTRL register: + COUNTFLAG: counter has reached zero + CLKSOURCE: select counter clock + TICKINT: enable interrupt + ENABLE: enable counter STK_LOAD register: 24 bit reset value STK_VAL register: current counter value ### Capture/Compare-Timer CR1 register: configure timer CNT register: counter value ARR register: reset value PSC register: pre-scale value, divide clock frequency CCR1-CCR4 registers: + compare with counter value and set output pin if counter surpasses the control value + on input (e. g. rising edge) capture the current counter value ``````