| | 1 | {{{ |
| | 2 | #!comment |
| | 3 | Page d'aide assembleur |
| | 4 | }}} |
| | 5 | [[PageOutline]] |
| | 6 | {{{ |
| | 7 | #!html |
| | 8 | <h1><u>Page d'aide assembleur</u></h1> |
| | 9 | }}} |
| | 10 | |
| | 11 | = Préambule = |
| | 12 | |
| | 13 | La difficulté de la programmation en assembleur PIC se résume en deux points: |
| | 14 | * ''seulement 35 instructions'',[[BR]] |
| | 15 | '''mais pas de structures de contrôle, pas de fonctions...''' |
| | 16 | * ''et quelques centaines d'octets de mémoire'',[[BR]] |
| | 17 | '''mais pas de typage, pas de pointeurs, pas de fichiers...''' |
| | 18 | |
| | 19 | La pauvreté du langage entraine des difficultés pour exprimer des choses aussi simples qu'un test IF-THEN-ELSE. Le but de |
| | 20 | cette page est de vous donner une aide sur la bonne façon d'écrire de l'assembleur PIC efficacement. Il n'y a aucune utilisation |
| | 21 | des périphériques internes ou externes du PIC. |
| | 22 | |
| | 23 | Le code que vous trouverez ici est issu de nombreuses <a href="liens.html">sources</a> à la fois sur internet et dans les |
| | 24 | livres. Les auteurs (ou sources) sont cités quand ils sont connus. |
| | 25 | |
| | 26 | = liste des instructions pic 16 = #instruction |
| | 27 | |
| | 28 | __'''Instructions sur les registres octet'''__:: |
| | 29 | ||'''`Mnémotique `'''||'''`arguments`'''||'''`Commentaire `'''||'''`drapeaux`'''||'''`cycles `'''|| |
| | 30 | || addwf || ''reg'', ''dst'' || add w to ''reg'', result in ''dst'' || z, dc, c || 1 || |
| | 31 | || andwf || ''reg'', ''dst'' || and w and ''reg'', result in ''dst'' || z || 1 || |
| | 32 | || clrf || ''reg'' || write zero to ''reg'' || z || 1 || |
| | 33 | || clrw || || write zero to w i || Z || 1 || |
| | 34 | || comf || ''reg'', ''dst'' || complement ''reg'', result in ''dst'' || Z || 1 || |
| | 35 | || decf || ''reg'', ''dst'' || decrement ''reg'', result in ''dst'' Z || Z || 1 || |
| | 36 | || incf || ''reg'', ''dst'' || Increment ''reg'', result in ''dst'' Z || Z || 1 || |
| | 37 | || iorwf || ''reg'', ''dst'' || Or W and ''reg'', result in ''dst'' || Z || 1 || |
| | 38 | || movf || ''reg'', ''dst'' || Move ''reg'' to ''dst'' || Z || 1 || |
| | 39 | || movwf || ''reg'' || Move W to ''reg'' || none || 1 || |
| | 40 | || nop || || No operation || none || 1 || |
| | 41 | || rlf || ''reg'', ''dst'' || Rotate ''reg'' left, result in ''dst'' || C || 1 || |
| | 42 | || rrf || ''reg'', ''dst'' || Rotate ''reg'' right, result in ''dst'' || C || 1 || |
| | 43 | || subwf || ''reg'', ''dst'' || Subtract W from ''reg'', result in ''dst'' || Z, DC, C || 1 || |
| | 44 | || swapf || ''reg'', ''dst'' || Swap nibbles of ''reg'', result in ''dst'' || none || 1 || |
| | 45 | || xorwf || ''reg'', ''dst'' || Xor W and ''reg'', result in ''dst'' || Z || 1 || |
| | 46 | || decfsz || ''reg'', ''dst'' || Decrement ''reg'', result in ''dst'', skip IF zero || none || 1 (2 if skip) || |
| | 47 | || incfsz || ''reg'', ''dst'' || Increment ''reg'', result in ''dst'', skip IF zero || none || 1 (2 if skip) || |
| | 48 | |
| | 49 | __'''Instructions sur les bits'''__:: |
| | 50 | ||'''`Mnémotique `'''||'''`arguments`'''||'''`Commentaire `'''||'''`drapeaux`'''||'''`cycles `'''|| |
| | 51 | || bcf || ''reg'', ''bit'' || Clear ''bit'' of ''reg'' || none || 1 || |
| | 52 | || bsf || ''reg'', ''bit'' || Set ''bit'' of ''reg'' || none || 1 || |
| | 53 | || btfsc || ''reg'', ''bit'' || Skip next instruction IF ''bit'' of ''reg'' is clear|| none || 1 (2 if skip) || |
| | 54 | || btfss || ''reg'', ''bit'' || Skip next instruction IF ''bit'' of ''reg'' is set || none || 1 (2 if skip) || |
| | 55 | |
| | 56 | __'''Instructions sur les immediats'''__:: |
| | 57 | ||'''`Mnémotique `'''||'''`arguments`'''||'''`Commentaire `'''||'''`drapeaux`'''||'''`cycles `'''|| |
| | 58 | || addlw || ''imm'' || Add immediate to W || Z, DC, C || 1 || |
| | 59 | || andlw || ''imm'' || And immediate to W || Z || 1 || |
| | 60 | || iorlw || ''imm'' || Inclusive OR littéral to W || Z || 1 || |
| | 61 | || movlw || ''imm'' || Move littéral to W || none || 1 || |
| | 62 | || retlw || ''imm'' || Load W with immediate and return || none || 2 || |
| | 63 | || sublw || ''imm'' || Subtract W from littéral || Z, DC, C || 1 || |
| | 64 | || xorlw || ''imm'' || Xor W and littéral || Z || 1 || |
| | 65 | |
| | 66 | __'''Instructions de controle'''__:: |
| | 67 | ||'''`Mnémotique `'''||'''`arguments`'''||'''`Commentaire `'''||'''`drapeaux`'''||'''`cycles `'''|| |
| | 68 | || clrwdt || || Reset watchdog timer || TO, PD || 1 || |
| | 69 | || call || ''addr'' || Call subroutine || none || 2 || |
| | 70 | || goto || ''addr'' || Go to ''addr'' || none || 2 || |
| | 71 | || retfie || || Return from interrupt || GIE || 2 || |
| | 72 | || return || || Return from subroutine || none || 2 || |
| | 73 | || sleep || || Enter sleep mode || TO, PD || 1 || |
| | 74 | |
| | 75 | = Structures de contrôle = #struc_ctrl |
| | 76 | |
| | 77 | == ` ` Branchements conditionnels == #test |
| | 78 | |
| | 79 | Comme vous le savez en assembleur, pour faire une rupture de séquence on ne sait faire qu'une chose: tester une condition et |
| | 80 | si cette condition est vraie ou fausse alors sauter à une adresse, c'est peu. En outre, en assembleur PIC, il y a une |
| | 81 | difficulté supplémentaire: si la condition est vraie on se contente de sauter une instruction. |
| | 82 | |
| | 83 | En PIC, il existe 4 instructions de sauts conditionnels: ''decfsz'', ''incfsz'', ''btfss'', ''btfsc.'' Les deux |
| | 84 | première instructions sont surtout utilisés pour les boucles. Nous allons ici, nous intéresser au comparaisons sur les nombres |
| | 85 | 8 bits signés (en complément à 2) et non signés, il y a 6 possibles: |
| | 86 | * égalité (== ou BEQ) |
| | 87 | * inégalité (!= ou BNE) |
| | 88 | * inférioité stricte (< ou BLT ou BLTS) |
| | 89 | * supériorité stricte (> ou BGT ou BGTS) |
| | 90 | * inférioité ou égalité (<= ou BLE ou BLES) |
| | 91 | * supériorité ou égalité (>= ou BGE ou BGES) |
| | 92 | |
| | 93 | Les registres doivent être dans le même banc. Le tableau qui suit donne en commentaire (après les ;) une notation de type |
| | 94 | macro instruction. Les comparaisons sont dépendent du type des données qui peuvent être non signées (valeur de 0 à 255) ou |
| | 95 | signées (valeurs de -128 à +127). Il est parfois nécessaire d'utiliser un registres temporaire TMP |
| | 96 | |
| | 97 | Égalité registre/registre et registre/immédiat:: |
| | 98 | {{{ |
| | 99 | ; si (REG1 == REG2) goto LAB |
| | 100 | ; BEQ REG1, REG2, goto, LAB |
| | 101 | movf REG1, W |
| | 102 | xorwf REG2, W |
| | 103 | btfsc STATUS, Z |
| | 104 | goto LAB |
| | 105 | }}} |
| | 106 | {{{ |
| | 107 | ; si (REG1 != REG2) goto LAB |
| | 108 | ; BNE REG1, REG2, goto, LAB |
| | 109 | movf REG1, W |
| | 110 | xorwf REG2, W |
| | 111 | btfss STATUS, Z |
| | 112 | goto LAB |
| | 113 | }}} |
| | 114 | {{{ |
| | 115 | ; si (REG == IMM) goto LAB |
| | 116 | ; BEQ REG, IMM, goto, LAB |
| | 117 | movlw IMM |
| | 118 | xorwf REG, W |
| | 119 | btfsc STATUS, Z |
| | 120 | goto LAB |
| | 121 | }}} |
| | 122 | {{{ |
| | 123 | ; si (REG1 != IMM) goto LAB |
| | 124 | ; BNE REG1, IMM, goto, LAB |
| | 125 | movlw IMM |
| | 126 | xorwf REG, W |
| | 127 | btfss STATUS, Z |
| | 128 | goto LAB |
| | 129 | }}} |
| | 130 | |
| | 131 | Comparaisons registre/registre sur des nombres non signés:: |
| | 132 | {{{ |
| | 133 | ; si (REG1 < REG2) goto LAB |
| | 134 | ; BLT REG1, REG2, goto, LAB |
| | 135 | movf REG2, W |
| | 136 | subwf REG1, W |
| | 137 | btfss STATUS, C |
| | 138 | goto LAB |
| | 139 | }}} |
| | 140 | {{{ |
| | 141 | ; si (REG1 > REG2) goto LAB |
| | 142 | ; BGT REG1, REG2, goto, LAB |
| | 143 | movf REG1, W |
| | 144 | subwf REG2, W |
| | 145 | btfss STATUS, C |
| | 146 | goto LAB |
| | 147 | }}} |
| | 148 | {{{ |
| | 149 | ; si (REG1 <= REG2) goto LAB |
| | 150 | ; BLE REG1, REG2, goto, LAB |
| | 151 | movf REG1, W |
| | 152 | subwf REG2, W |
| | 153 | btfsc STATUS, C |
| | 154 | goto LAB |
| | 155 | }}} |
| | 156 | {{{ |
| | 157 | ; si (REG1 >= REG2) goto LAB |
| | 158 | ; BGE REG1, REG2, goto, LAB |
| | 159 | movf REG2, W |
| | 160 | subwf REG1, W |
| | 161 | btfsc STATUS, C |
| | 162 | goto LAB |
| | 163 | }}} |
| | 164 | |
| | 165 | Comparaisons registre/immediat sur des nombres non signés:: |
| | 166 | {{{ |
| | 167 | ; si (REG > IMM) goto LAB |
| | 168 | ; BGT REG, IMM, goto, LAB |
| | 169 | movf REG, W |
| | 170 | sublw IMM |
| | 171 | btfss STATUS, C |
| | 172 | goto LAB |
| | 173 | }}} |
| | 174 | {{{ |
| | 175 | ; si (REG < IMM) goto LAB |
| | 176 | ; BLT REG, IMM, goto, LAB |
| | 177 | movlw IMM |
| | 178 | subwf REG, W |
| | 179 | btfss STATUS, C |
| | 180 | goto LAB |
| | 181 | }}} |
| | 182 | {{{ |
| | 183 | ; si (REG <= IMM) goto LAB |
| | 184 | ; BLE REG, IMM, goto, LAB |
| | 185 | movf REG, W |
| | 186 | sublw IMM |
| | 187 | btfsc STATUS, C |
| | 188 | goto LAB |
| | 189 | }}} |
| | 190 | {{{ |
| | 191 | ; si (REG >= IMM) goto LAB |
| | 192 | ; BGE REG, IMM, goto, LAB |
| | 193 | movlw IMM |
| | 194 | subwf REG, W |
| | 195 | btfsc STATUS, C |
| | 196 | goto LAB |
| | 197 | }}} |
| | 198 | |
| | 199 | Comparaisons immediat/registre sur des nombres non signés:: |
| | 200 | {{{ |
| | 201 | ; si (IMM < REG) goto LAB |
| | 202 | ; BLT IMM, REG, goto, LAB |
| | 203 | movf REG,W |
| | 204 | sublw IMM |
| | 205 | btfss STATUS, C |
| | 206 | goto LAB |
| | 207 | }}} |
| | 208 | {{{ |
| | 209 | ; si (IMM > REG) goto LAB |
| | 210 | ; BGT IMM, REG, goto, LAB |
| | 211 | movlw IMM |
| | 212 | subwf REG,W |
| | 213 | btfss STATUS, C |
| | 214 | goto LAB |
| | 215 | }}} |
| | 216 | {{{ |
| | 217 | ; si (IMM <= REG) goto LAB |
| | 218 | ; BLE IMM, REG, goto, LAB |
| | 219 | movlw IMM |
| | 220 | subwf REG,W |
| | 221 | btfsc STATUS, C |
| | 222 | goto LAB |
| | 223 | |
| | 224 | }}} |
| | 225 | {{{ |
| | 226 | ; si (IMM >= REG) goto LAB |
| | 227 | ; BGE IMM, REG, goto, LAB |
| | 228 | movf REG,W |
| | 229 | sublw IMM |
| | 230 | btfsc STATUS, C |
| | 231 | goto LAB |
| | 232 | |
| | 233 | }}} |
| | 234 | |
| | 235 | comparaisons registre/registre sur des nombres signés:: |
| | 236 | {{{ |
| | 237 | ; si (REG1 < REG2) goto LAB |
| | 238 | ; BLTS REG1, REG2, goto, LAB |
| | 239 | movf REG1, W |
| | 240 | addlw 0x80 |
| | 241 | movwf TMP |
| | 242 | movf REG2, W |
| | 243 | addlw 0x80 |
| | 244 | subwf TMP, W |
| | 245 | btfss STATUS, C |
| | 246 | goto LAB |
| | 247 | }}} |
| | 248 | {{{ |
| | 249 | ; si (REG1 > REG2) goto LAB |
| | 250 | ; BGTS REG1, REG2, goto, LAB |
| | 251 | movf REG2, W |
| | 252 | addlw 0x80 |
| | 253 | movwf TMP |
| | 254 | movf REG1, W |
| | 255 | addlw 0x80 |
| | 256 | subwf TMP, W |
| | 257 | btfss STATUS, C |
| | 258 | goto LAB |
| | 259 | }}} |
| | 260 | {{{ |
| | 261 | ; si (REG1 <= REG2) goto LAB |
| | 262 | ; BLES REG1, REG2, goto, LAB |
| | 263 | movf REG2, W |
| | 264 | addlw 0x80 |
| | 265 | movwf TMP |
| | 266 | movf REG1, W |
| | 267 | addlw 0x80 |
| | 268 | subwf TMP, W |
| | 269 | btfsc STATUS, C |
| | 270 | goto LAB |
| | 271 | }}} |
| | 272 | {{{ |
| | 273 | ; si (REG1 >= REG2) goto LAB |
| | 274 | ; BGES REG1, REG2, goto, LAB |
| | 275 | movf REG1, W |
| | 276 | addlw 0x80 |
| | 277 | movwf TMP |
| | 278 | movf REG2, W |
| | 279 | addlw 0x80 |
| | 280 | subwf TMP, W |
| | 281 | btfsc STATUS, C |
| | 282 | goto LAB |
| | 283 | }}} |
| | 284 | Comparaisons registre/immediat sur des nombres signés:: |
| | 285 | {{{ |
| | 286 | ; si (REG < IMM) goto LAB |
| | 287 | ; BLTS REG, IMM, goto, LAB |
| | 288 | movf REG, W |
| | 289 | addlw 0x80 |
| | 290 | movwf TMP |
| | 291 | movlw 0x80 | IMM |
| | 292 | subwf TMP, W |
| | 293 | btfss STATUS, C |
| | 294 | goto LAB |
| | 295 | }}} |
| | 296 | {{{ |
| | 297 | ; si (REG > IMM) goto LAB |
| | 298 | ; BGTS REG, IMM, goto, LAB |
| | 299 | movf REG, W |
| | 300 | addlw 0x80 |
| | 301 | sublw 0x80 | IMM |
| | 302 | btfss STATUS, C |
| | 303 | goto LAB |
| | 304 | }}} |
| | 305 | {{{ |
| | 306 | ; si (REG <= IMM) goto LAB |
| | 307 | ; BLES REG, IMM, goto, LAB |
| | 308 | movf REG, W |
| | 309 | addlw 0x80 |
| | 310 | sublw 0x80 | IMM |
| | 311 | btfsc STATUS, C |
| | 312 | goto LAB |
| | 313 | }}} |
| | 314 | {{{ |
| | 315 | ; si (REG >= IMM) goto LAB |
| | 316 | ; BGES REG, IMM, goto, LAB |
| | 317 | movf REG, W |
| | 318 | addlw 0x80 |
| | 319 | sublw 0x80 | IMM |
| | 320 | btfss STATUS,Z |
| | 321 | btfss STATUS, C |
| | 322 | goto LAB |
| | 323 | }}} |
| | 324 | Comparaisons immediat/registre sur des nombres signés:: |
| | 325 | {{{ |
| | 326 | ; si (IMM < REG) goto LAB |
| | 327 | ; BLTS IMM, REG, goto, LAB |
| | 328 | movf REG,W |
| | 329 | addlw 0x80 |
| | 330 | sublw 0x80 | IMM |
| | 331 | btfss STATUS, C |
| | 332 | goto LAB |
| | 333 | |
| | 334 | }}} |
| | 335 | {{{ |
| | 336 | ; si (IMM > REG) goto LAB |
| | 337 | ; BGTS IMM, REG, goto, LAB |
| | 338 | movf REG,W |
| | 339 | addlw 0x80 |
| | 340 | sublw 0x80 | IMM |
| | 341 | btfsc STATUS,Z |
| | 342 | goto $+3 |
| | 343 | btfsc STATUS,C |
| | 344 | goto LAB |
| | 345 | }}} |
| | 346 | {{{ |
| | 347 | ; si (IMM <= REG) goto LAB |
| | 348 | ; BLES IMM, REG, goto, LAB |
| | 349 | movf REG,W |
| | 350 | addlw 0x80 |
| | 351 | movwf TMP |
| | 352 | movlw 0x80 | IMM |
| | 353 | subwf TMP,W |
| | 354 | btfsc STATUS, C |
| | 355 | goto LAB |
| | 356 | |
| | 357 | }}} |
| | 358 | {{{ |
| | 359 | ; si (IMM >= REG) goto LAB |
| | 360 | ; BGES IMM, REG, goto, LAB |
| | 361 | movf REG,W |
| | 362 | addlw 0x80 |
| | 363 | sublw 0x80 | IMM |
| | 364 | btfsc STATUS, C |
| | 365 | goto LAB |
| | 366 | |
| | 367 | }}} |
| | 368 | |
| | 369 | == ` ` If condition then else == #if_then_else |
| | 370 | |
| | 371 | Pour pouvoir faire une alternative, il faut savoir faire un <a href="#test">branchement conditionnel</a>. Nous supposons que |
| | 372 | nous savons le faire. Dans une alternative ''si-alors-sinon'', nous allons mettre la séquence ''alors'' avant la séquence |
| | 373 | ''sinon''. Ce choix permet, a priori, une plus grande lisibilité du code, car il est plus proche du code écrit dans les |
| | 374 | langages évolués de type C ou Pascal. Pour respecter cet ordre, il est souvent nécessaire d'inverser le test. En effet, si la |
| | 375 | condition est fausse, il faut sauter à la séquence ''sinon'' et donc simplement continuer si la condition est vraie. |
| | 376 | |
| | 377 | Quand les conditions sont plus complexes, qu'elles sont le résultat d'une expression Booléenne, il faut faire des séquences |
| | 378 | de test. Le tableau suivant contient quelques exemples permettant de comprendre la méthode à suivre. Ce n'est pas une méthode générale |
| | 379 | |
| | 380 | SI test ALORS sequence_alors SINON sequence_sinon FIN:: |
| | 381 | * Cas général: |
| | 382 | {{{ |
| | 383 | IFNOT test GOTO sinon |
| | 384 | alors sequence_alors |
| | 385 | goto fin |
| | 386 | sinon sequence_sinon |
| | 387 | fin |
| | 388 | }}} |
| | 389 | Exemple: si (reg1==reg2) alors sequence_alors SINON sequence_sinon FIN |
| | 390 | {{{ |
| | 391 | si ; BNE reg1, reg2, goto, sinon |
| | 392 | movf reg1,w |
| | 393 | xorwf reg2,w |
| | 394 | btfss STATUS, Z |
| | 395 | goto sinon |
| | 396 | |
| | 397 | alors sequence_alors |
| | 398 | goto fin |
| | 399 | |
| | 400 | sinon sequence_sinon |
| | 401 | fin |
| | 402 | }}} |
| | 403 | |
| | 404 | SI test1 ET test2 ALORS sequence_alors SINON sequence_sinon FIN:: |
| | 405 | {{{ |
| | 406 | si IFNOT test1 GOTO sinon |
| | 407 | IFNOT test2 GOTO sinon |
| | 408 | alors sequence_alors |
| | 409 | goto fin |
| | 410 | sinon sequence_sinon |
| | 411 | fin |
| | 412 | }}} |
| | 413 | |
| | 414 | SI test1 OU test2 ALORS sequence_alors SINON sequence_sinon FIN:: |
| | 415 | {{{ |
| | 416 | si IF test1 GOTO alors |
| | 417 | IFNOT test2 GOTO sinon |
| | 418 | alors sequence_alors |
| | 419 | goto fin |
| | 420 | sinon sequence_sinon |
| | 421 | fin |
| | 422 | }}} |
| | 423 | SI (test1 OU test2) ET (test3 OU test4) ALORS sequence_alors SINON sequence_sinon FIN:: |
| | 424 | {{{ |
| | 425 | si IF test1 GOTO si2 |
| | 426 | IFNOT test2 GOTO sinon |
| | 427 | si2 IF test3 GOTO alors |
| | 428 | IFNOT test4 GOTO sinon |
| | 429 | alors sequence_alors |
| | 430 | goto fin |
| | 431 | sinon sequence_sinon |
| | 432 | fin |
| | 433 | }}} |
| | 434 | SI (test1 ET test2) OU (test3 ET test4) ALORS sequence_alors SINON sequence_sinon:: |
| | 435 | {{{ |
| | 436 | si IFNOT test1 GOTO si2 |
| | 437 | IF test2 GOTO alors |
| | 438 | si2 IFNOT test3 GOTO sinon |
| | 439 | IFNOT test4 GOTO sinon |
| | 440 | alors sequence_alors |
| | 441 | goto fin |
| | 442 | sinon sequence_sinon |
| | 443 | fin |
| | 444 | }}} |
| | 445 | |
| | 446 | == ` ` Faire n fois == #faire_n_fois |
| | 447 | |
| | 448 | On traite deux cas, si N est sur 8 bits ou si N est sur 16 bits. Dans le cas 8 bits, la valeur 0 est en fait 256. Dans le |
| | 449 | cas 16 bits, la valeur 0 c'est vraiment 0 (c'est-à-dire qu'on n'exécute pas la séquence_corps). |
| | 450 | |
| | 451 | <table cellpadding="10" summary="fairenfois"> |
| | 452 | <tr> |
| | 453 | <td colspan="4"><a name="fairenfois8bits"><b>Faire N fois (8 bits) sequence_corps FIN</b></a></td> |
| | 454 | </tr> |
| | 455 | <tr valign="top"> |
| | 456 | <td></td> |
| | 457 | <td> |
| | 458 | Si N est une valeur immédiate. |
| | 459 | {{{ |
| | 460 | movlw N |
| | 461 | movwf REG |
| | 462 | corps sequence_corps |
| | 463 | decfsz REG |
| | 464 | goto corps |
| | 465 | }}} |
| | 466 | </td> |
| | 467 | <td> |
| | 468 | Si N est dans un registre. |
| | 469 | {{{ |
| | 470 | movf REG_N, W |
| | 471 | movwf REG |
| | 472 | corps sequence_corps |
| | 473 | decfsz REG |
| | 474 | goto corps |
| | 475 | }}} |
| | 476 | * Faire N fois (16 bits) sequence_corps FIN |
| | 477 | Si N est une valeur immédiate:: |
| | 478 | {{{ |
| | 479 | movlw (HIGH N) + 1 |
| | 480 | movwf REG+1 |
| | 481 | movlw LOW N |
| | 482 | movwf REG |
| | 483 | movf REG, F |
| | 484 | btfsc STATUS, Z |
| | 485 | goto testh |
| | 486 | corps sequence_corps |
| | 487 | decfsz REG |
| | 488 | goto corps |
| | 489 | testh decfsz REG+1 |
| | 490 | goto corps |
| | 491 | fin |
| | 492 | }}} |
| | 493 | Si N est dans une paire de registres successifs:: |
| | 494 | {{{ |
| | 495 | incf REG_N+1, W |
| | 496 | movwf REG+1 |
| | 497 | movf REG_N, W |
| | 498 | movwf REG |
| | 499 | btfsc STATUS, Z |
| | 500 | goto testh |
| | 501 | corps sequence_corps |
| | 502 | decfsz REG |
| | 503 | goto corps |
| | 504 | testh decfsz REG+1 |
| | 505 | goto corps |
| | 506 | fin |
| | 507 | }}} |
| | 508 | |
| | 509 | == ` ` Switch case == #switchcase |
| | 510 | |
| | 511 | Le switch case est un test à choix multiples. Il existe dans tous les langages évolués et permet entre autre de décrire les |
| | 512 | automates d'états finis particulièrement important dans la programmation en assembleur. |
| | 513 | |
| | 514 | La forme générale du switch case est:: |
| | 515 | {{{ |
| | 516 | switch reg |
| | 517 | case CST1 : sequence_cst1; break; |
| | 518 | case CST2 : sequence_cst2; break; |
| | 519 | case CST3 : sequence_cst3; break; |
| | 520 | default : sequence_default |
| | 521 | end |
| | 522 | }}} |
| | 523 | |
| | 524 | Les valeurs CST peuvent être quelconque. Dans ce cas, il n'y a d'autres choix que de faire les tests les uns après les |
| | 525 | autres en séquence. Dans le code qui suit, on suppose que les constantes sont bien des valeurs immédiates mais en fait il peut |
| | 526 | s'agir de registres. On peut même faire des tests différents. C'est très général mais évidemment ce n'est pas très effice et |
| | 527 | tous les tests ne sont pas équivalent vis à vis du temps de traitement. Le premier est favorisé par rapport au dernier. |
| | 528 | |
| | 529 | switch general:: |
| | 530 | Si les valeurs constantes sont quelconques: |
| | 531 | {{{ |
| | 532 | ; BEQ reg, CST1, goto, label_cst1 |
| | 533 | movlw CST1 |
| | 534 | xorwf reg, W |
| | 535 | btfsc STATUS, Z |
| | 536 | goto label_cst1 |
| | 537 | |
| | 538 | ; BEQ reg, CST2, goto, label_cst2 |
| | 539 | movlw CST2 |
| | 540 | xorwf reg, W |
| | 541 | btfsc STATUS, Z |
| | 542 | goto label_cst2 |
| | 543 | |
| | 544 | ; BEQ reg, CST3, goto, label_cst3 |
| | 545 | movlw CST3 |
| | 546 | xorwf reg, W |
| | 547 | btfsc STATUS, Z |
| | 548 | goto label_cst3 |
| | 549 | |
| | 550 | ; BEQ reg, CST4, goto, label_cst4 |
| | 551 | movf CST4 |
| | 552 | xorwf reg, W |
| | 553 | btfsc STATUS, Z |
| | 554 | goto label_cst4 |
| | 555 | }}} |
| | 556 | {{{ |
| | 557 | ; puis a la suite des tests |
| | 558 | ; les sequences a executer |
| | 559 | |
| | 560 | sequence_default |
| | 561 | |
| | 562 | label_cst1 |
| | 563 | sequence_cst1 |
| | 564 | goto fin |
| | 565 | |
| | 566 | label_cst2 |
| | 567 | sequence_cst2 |
| | 568 | goto fin |
| | 569 | |
| | 570 | label_cst3 |
| | 571 | sequence_cst3 |
| | 572 | goto fin |
| | 573 | |
| | 574 | label_cst4 |
| | 575 | sequence_cst4 |
| | 576 | goto fin |
| | 577 | |
| | 578 | fin |
| | 579 | }}} |
| | 580 | |
| | 581 | mais pour être efficace, il est souhaitable de se contraindre dans le choix des valeurs. |
| | 582 | |
| | 583 | == ` ` Tantque condition faire == #tantque |
| | 584 | |
| | 585 | = Arithmétiques = #arith |
| | 586 | |
| | 587 | == ` ` Entière 8 bits == #int9 |
| | 588 | |
| | 589 | * Addition |
| | 590 | * Soustraction |
| | 591 | * Multiplication |
| | 592 | * Division |
| | 593 | |
| | 594 | == ` ` Entière 16 bits == #int16 |
| | 595 | |
| | 596 | == ` ` Virgule fixe 16 bits == #vfixe16 |
| | 597 | |
| | 598 | == ` ` Flottante 16 bits == #float16 |
| | 599 | |
| | 600 | = Expressions = #expr |
| | 601 | |
| | 602 | == ` ` Boolèennes == #exp_bool |
| | 603 | |
| | 604 | == ` ` Arithmétiques == #exp_arith |
| | 605 | |
| | 606 | = Structures de données = #struc_data |
| | 607 | |
| | 608 | == ` ` Tableaux de données == #tables |
| | 609 | |
| | 610 | * Dans les registres |
| | 611 | * Dans le programme |
| | 612 | |
| | 613 | == ` ` Liste chainée == #listes |
| | 614 | |
| | 615 | == ` ` Pile == #piles |
| | 616 | |
| | 617 | = Macroinstructions = #macros |
| | 618 | |
| | 619 | = Automates = #automates |
| | 620 | |
| | 621 | = Routines diverses (snippets) = #snippets |
| | 622 | |
| | 623 | == ` ` Mathématiques == #snippets_math |
| | 624 | |
| | 625 | * Parité |
| | 626 | * Moyenne glissante |
| | 627 | * PGCD |