| 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 |