HSG |
|
Das folgende kleine Programm sollte nicht wirklich in den PIC geladen werden, sondern mit Hilfe des Debuggers bearbeitet werden. Es soll die Bedeutung und Wirkung der Flags bei arithmetischen Operationen zeigen. Bei der Operation 7+11 wird das Digit-Carry gesetzt, warum? Wann wird das Carry-Flag gesetzt, wann das Zero-Flag? Zur Klärung dieser Fragen soll das Programm variiert werden. Das Original-Handbuch erläutert das STATUS-Register auf Seite 22. Eine prima "Lesson" zum Thema ist bei John McDonoughs PIC Elmer 160 Course Lessons zu finden.
processor pic16f877a #include p16f877a.inc __config _HS_OSC & _WDT_OFF & _PWRTE_ON ; Variablen S1 equ 0x20 ; 1.Summand S2 equ 0x21 ; 2.Summand org 0x00 reset clrf STATUS movlw 0x00 movwf PCLATH goto main org 0x10 main movlw d'7' movwf S1 movlw d'11' movwf S2 bcf STATUS,C ; Carry-Flag zurücksetzen bcf STATUS,DC ; Digit-Carry-Flag zurücksetzen bcf STATUS,Z ; Zero-Flag zurücksetzen movfw S1 addwf S2,f loop goto loop end
Wer nicht den Simulator benutzen will, kann sich durch folgenden Code das STATUS-Register und damit die Flags auch auf PortB ausgeben lassen:
; Port-Setup bsf STATUS,5 ; wechsle zu Bank1 movlw b'00000000' ; setze Port B, Bit 0-7 movwf TRISB ; als Ausgang bcf STATUS,5 ; wieder in Bank 0 wechseln ; STATUS auf PortB ausgeben movfw STATUS movwf PORTB
bcf STATUS,C ; Carry-Flag löschen rlf y,1 bcf STATUS,C ; Carry-Flag löschen rrf x,1
Ein passender Algorithmus ist die sogenannte ägyptische Bauern-Multiplikation .
# -*- coding: iso-8859-1 -*- # Autor: mk, 29.1.09 x = 13 y = 17 p = 0 while x > 0: if x%2 == 1: p = p + y y = y*2 x = x/2 print p
processor pic16f877a #include p16f877a.inc __config _HS_OSC & _WDT_OFF & _PWRTE_ON ; Variablen x equ 0x20 ; 1.Faktor y equ 0x21 ; 2.Faktor p equ 0x22 ; Produkt org 0x00 reset clrf STATUS movlw 0x00 movwf PCLATH goto main org 0x10 main movlw d'13' movwf x movlw d'17' movwf y movlw 0x0 movwf p sb movf x,1 btfsc STATUS,Z ; x = 0? goto se ; x = 0 btfss x,0 ; x ungerade? goto notaddy ; x gerade movf p addwf y,0 movwf p notaddy bcf STATUS,C ; Carry-Flag löschen rlf y,1 bcf STATUS,C ; Carry-Flag löschen rrf x,1 goto sb se loop goto loop end
# -*- coding: iso-8859-1 -*- # Autor: mk, 9.6.09 x = 101 y = 23 q = 0 r = x while r-y >= 0: r = r-y q = q+1 print x,'div',y,'=',q print x,'mod',y,'=',r
processor pic16f877a #include p16f877a.inc __config _HS_OSC & _WDT_OFF & _PWRTE_ON ; Variablen x equ 0x20 y equ 0x21 q equ 0x22 r equ 0x23 org 0x00 reset: clrf STATUS movlw 0x00 movwf PCLATH goto main org 0x10 main: ; Eingaben movlw d'101' movwf x movlw d'23' movwf y ; Division call divmod ; Dauerschleife loop: goto loop ; -------------------------------------------- divmod: movlw d'0' ; q -> 0 movwf q movf x,0 ; x -> r movwf r bsf STATUS,C ; Carry-Flag setzen dmloop: movf y,0 ; y -> w subwf r,0 ; r-w -> w btfsc STATUS,C ; Carry-Flag wird bei Unterlauf gelöscht goto dmweiter goto dmunterlauf dmweiter: movf y,0 ; y -> w subwf r,1 ; r-w -> r incf q ; q+1 -> q goto dmloop dmunterlauf: return ; -------------------------------------------- end