PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ORG Anweisung - RN-Wissen-Artikel



Matze235
11.01.2017, 13:30
Guten Tag zusammen,

ich versuche gerade, den Assembler-Code eines nicht mehr verfügbaren Kollegen zu verstehen.

Dieser ist geschrieben für einen PIC 12C672.

Eine der letzten Unklarheiten stellt die Verwendung der ORG-Anweisung dar.

So sieht der Code grob aus:



list p=12C672 ; Prozessortyp
; list directive to define processor
#include <p12c672.inc> ; processor specific variable definitions

__CONFIG _CP_ALL & _PWRTE_ON & _WDT_OFF & _WDTE_OFF & _HS_OSC


... EQU ...
... etliche EQU Registeradressen-Benennungen

#define ..
... einige #define - Anweisungen

org 5
goto start

; Initialisierung

; Main - Dauerschleife

org 03ffh
return

end



Ich kann mir nicht erklären, welchen Zweck das
org 5 erfüllen sollte.

Edit: Dass es den Platz im Speicher angibt, ab wo der folgende Code im PIC abgelegt werden soll, habe ich mittlerweile verstanden.
Warum nimmt man dann aber die Adresse 0x05 und nicht einfach die 0x00?

Hat da jemand eine Idee?

Wenn ich den Code mit MPLAB X IDE v3.50 im Simulator versuche zu debuggen, kommt bei mir die Fehlermeldung
no source code lines were found at current pc 0x0.

Wenn ich den Code auf
org 0 ändere, funktioniert das debuggen problemlos.

Ich verstehe nur leider weder die Fehlermeldung noch den Grund, warum die Fehlermeldung nach dieser Änderung nicht mehr auftaucht.



Desweiteren verstehe ich die Verwendung der ORG-Anweisung auf in folgendem Artikel an mehreren Stellen nicht:
http://rn-wissen.de/wiki/index.php?title=PIC_Assembler



org 0x03B8 ; diese Adresse kann gleich max.Adresse - 47h sein

org 0x0023 ; hier fängt das "Erstes" an

ORG 0x0358 ; diese Adresse kann gleich max.Adresse - A7h sein

org 0x3EF ; diese Adresse kann gleich max.Adresse - 10h sein

org 0x001E ; ab da kann eigener Code anfangen

org 0x3DF ; diese Adresse kann gleich max.Adresse - 20h sein


Wie kommt man auf genau diese spezifischen Speicherstellen?

Besten Dank im Voraus!
Wenn ihr weitere Informationen von mir braucht, bekommt Ihr die natürlich gerne!

Beste Grüße
Matze

PICture
11.01.2017, 15:47
Hallo!

Die "ORG" Direktive definiert wo im Programmspeicher der ganze nachfolgende Assemblercode bis nächste Direktive "ORG" bzw. "END" per verwendeten Compilerprogramm beim "flaschen" abgelegt werden soll. Die Adressen wählt man beliebig selber. ;)

Siro
11.01.2017, 20:01
Der Prozessor fängt beim Einschalten oder Reset immer an der Speicherstelle 0 an
Dort steht dann meist ein Goto Start
Dieser Start ist dann das Hauptprogramm, was sich etwas weiter hinten im Code befindet.
Der Grund dafür ist: An Speicherstelle 4 befindet sich der Interrupt-Vector
und da soll natürlich drüber weg gesprungen werden.




MAIN_CODE CODE
ORG 0 ; Reset Vector, hier gehts immer los nach dem Einschalten
goto Main ; hier steht normalereise ein Goto Hauptprogramm

ORG 4 ; addresse des Interrupt vectors ist fest und immer an Adresse 4 bei diesem Chip
goto InterruptCode

; hier ist nun die Speicherstelle 5
Main:
....
....
goto Main ; Hauptschleife

InterruptCode:




Hier ist noch ein Beispiel:
Der obere Speicher 0..3 wird hier direkt mit Code gefüllt. Ab Speicherstelle 4 beginnt die Interrupt Funktion
Das Hauptprogramm liegt dann irgendwo weiter hinten....


ResetVector CODE H'0000' ; always fixed to address 0x0000
NOP
NOP
clrf STATUS
goto main

;--------------------------------------------------------------------
; I N T E R R U P T - V E C T O R
;
InterruptVector CODE H'0004' ; always fixed to address 0x0004
Interrupt:
movwf Save_Wreg
swapf STATUS,W
movwf Save_Status

btfsc INTCON,TMR0IF ; Timer 0 ; 1 ms Interrupt
goto TIMER0_Interrupt

InterruptEnd:
swapf Save_Status,W
movwf STATUS
swapf Save_Wreg,F
swapf Save_Wreg,W
retfie
;--------------------------------------------------------------------
TIMER0_Interrupt:
bcf INTCON,TMR0IF
goto InterruptEnd
;--------------------------------------------------------------------

main:
;
goto main


Auszug aus dem Datenblatt:
32340


Siro

Matze235
12.01.2017, 08:43
Ich verwende allerdings keine Interrupt-Funktionen.
Muss die Adresse 0x04 dann trotzdem frei bleiben?

Ich habe den Code nach deinen Vorgaben mal ein wenig angepasst:




list p=12C672

#include <p12c672.inc>

__CONFIG _CP_ALL & _PWRTE_ON & _WDT_OFF & _WDTE_OFF & _HS_OSC


... EQU ...
;... etliche EQU Registeradressen-Benennungen

#define ..
;... einige #define - Anweisungen

org 0 ; # geänderter Code, Simulation möglich
goto start

; -------------------------------------
; Ganz viele Funktionen/Unterprogramme
; -------------------------------------

start ;org 05h ; # Speicherstelle 05h führt zu Fehlermeldungen
org 36h ; # erste Speicherstelle, an der der BUILD ohne Fehler abgeschlossen werden konnte

; -------------------------------------
; Initialisierungen
; -------------------------------------

main
call heat_function

call wait_function

call meas_function

goto main



Folgende Fehlermeldung erscheint, wenn ich " org 05h " verwende:



CLEAN SUCCESSFUL (total time: 102ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/AS/MPLABXProjects/CO_Sensor_V01_1.X'
make -f nbproject/Makefile-default.mk dist/default/production/CO_Sensor_V01_1.X.production.hex
make[2]: Entering directory 'C:/Users/AS/MPLABXProjects/CO_Sensor_V01_1.X'
"C:\Program Files (x86)\Microchip\MPLABX\v3.50\mpasmx\mpasmx.exe" -q -p12c672 -l"build/default/production/cose_v01_1.lst" -e"build/default/production/cose_v01_1.err" -o"build/default/production/cose_v01_1.o" "cose_v01_1.asm"
Message[302] C:\USERS\AS\MPLABXPROJECTS\CO_SENSOR_V01_1.X\COSE_ V01_1.ASM 271 : Register in operand not in bank 0. Ensure that bank bits are correct.
make[2]: *** [dist/default/production/CO_Sensor_V01_1.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
"C:\Program Files (x86)\Microchip\MPLABX\v3.50\mpasmx\mplink.exe" -p12c672 -w -m"dist/default/production/CO_Sensor_V01_1.X.production.map" -z__MPLAB_BUILD=1 -odist/default/production/CO_Sensor_V01_1.X.production.cof build/default/production/cose_v01_1.o
MPLINK 5.08, LINKER
Device Database Version 1.34
Copyright (c) 1998-2011 Microchip Technology Inc.
Error - section '.org_1' can not fit the absolute section. Section '.org_1' start=0x00000005, length=0x00000022
Errors : 1

nbproject/Makefile-default.mk:118: recipe for target 'dist/default/production/CO_Sensor_V01_1.X.production.hex' failed
make[2]: Leaving directory 'C:/Users/AS/MPLABXProjects/CO_Sensor_V01_1.X'
nbproject/Makefile-default.mk:84: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/AS/MPLABXProjects/CO_Sensor_V01_1.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed

BUILD FAILED (exit value 2, total time: 1s)


Erst bei " org 36h " taucht dieser Fehler nicht mehr auf.
Gibt es eine Möglichkeit, ohne lästige Probiererei herauszufinden, wo meine Start-Funktion beginnen darf?

PICture
12.01.2017, 08:56
Ja, durch Schreiben ASM Quellcoden entsprechend geprüften Ablaufdiagrammen. ;)

Matze235
12.01.2017, 10:56
Tut mir leid, ich verstehe nicht, was du mir sagen willst.

witkatz
12.01.2017, 11:44
Gibt es eine Möglichkeit, ohne lästige Probiererei herauszufinden, wo meine Start-Funktion beginnen darf?

Kommentiere das ORG aus, übersetze das Projekt für Debugmodus und schau im Listing (Window->Debugging->Output->Disassemby Listing File) nach, auf welche Adresse der Linker deine main bzw. die erste Anweisung nach start allokiert hat (erste Spalte im Listing). Das müsste dann die nächste freie Adresse sein, die der Linker gefunden hat.
Warum musst du die start-Marke überhaupt selber allokieren? Vielleicht brauchst du das ORG an der Stelle überhaupt nicht?

Matze235
12.01.2017, 12:23
Super! Besten Dank!
Das ist genau das, was ich gesucht habe!
Vielen Dank! Das Disassemby Listing File hat mir sehr weitergeholfen!

Das "ORG 0x00" kann ich mir anscheinend sparen, wie es scheint. Richtig?

Ich verwende -wie gesagt- keine Interrupt-Funktionen.
Muss die Adresse 0x04 dann trotzdem frei bleiben?

Wenn ich "ORG 0x00" und "ORG 0x05" beide weglasse, bekomme ich zumindest etliche Fehlermeldungen.
Eines von beiden muss ich anscheinend mindestens vorgeben.

PICture
12.01.2017, 14:49
Nix zu danken. Ich freue mich immer sehr, wenn ich noch helfen konnte. :Strahl


Das "ORG 0x00" kann ich mir anscheinend sparen, wie es scheint. Richtig?

Keine Ahnung (kurz: k.A.). :confused:


Muss die Adresse 0x04 dann trotzdem frei bleiben?

k.A. :confused: Vorsichsweise habe ich sie immer übersprungen.


Wenn ich "ORG 0x00" und "ORG 0x05" beide weglasse, bekomme ich zumindest etliche Fehlermeldungen.

k.A. :confused: Ich verwende anderes ASS Programm, wo man mehrere Fehlermeldungen ruhig ignorieren kann.

Sorry, aber ich kann nur Fragen über mir schon bekannte Probleme beantworten. ;)

witkatz
12.01.2017, 15:39
Das "ORG 0x00" kann ich mir anscheinend sparen, wie es scheint. Richtig?
den Reset Vektor würde ich schon drin lassen

Muss die Adresse 0x04 dann trotzdem frei bleiben?
Wenn du die Gründe nicht kennst, warum der Interruptvektor frei gelassen wurde, lass ihn frei, wenn es nicht weh tut.

org 0 ; # geänderter Code, Simulation möglich
goto start
org 5Damit müsste es getan sein. Für die Marke start brauchst du mE wahrscheinlich keine absolute Adresse. Weitere org brauchst du im Quellcode dann, wenn "computed goto", sprich Tabellen verwendet werden. Das ist in PICtures Artikel http://rn-wissen.de/wiki/index.php?title=PIC_Assembler#Tabellen recht gut erklärt.

Nachtrag
Ich werd das Gefühl nicht los, dass das erste von dir gepostete Quellcode nur ein Teil des Softwareprojektes ist. Es wundert mich, dass der Bereich ab Resetvektor leer war. Kann es sein, dass irgendein #include bereits gelöscht wurde, oder zu dem Softwareprojekt noch weitere Dateien dazu gehört haben, die der MPLINK ursprünglich zusammengelinkt hat? Liegt dir das komplette Softwareprojekt mit allen Dateien und Linkerskript vor?

Matze235
13.01.2017, 09:16
Ich nehme an, du meinst folgenden Beginn des Codes in dieser Art?

(Ich habe die Start- und die Main-Funktion jetzt direkt nach die CONFIGs, EQUs und #designs in meinen Quellcode platziert)



org 00h
goto start

;************************************************* ************************
; # START - PIN Configuration, TIMER Confuguration, OSZILLATOR Calibration, AD-CONVERTER definieren
;
start org 05h



Das, womit ich arbeite, ist nur eine einzelne ASM-Datei mit noch 6 weiteren Dateien. Ich habe mal einen Screenshot angehängt.

32343

Und in der Simulation läuft's ja jetzt auch einwandfrei.. keine Ahnung, was da fehlen könnte..

RoboHolIC
13.01.2017, 15:17
Ich vermute, dass im Debugging-Mode ein Interrupt benötigt wird. Der für das debuggen erforderliche zusätzliche Code wird von der IDE automatisch erzeugt und eingefügt. Das obige Konstrukt stellt jedenfalls sicher, dass das Hauptprogramm Platz für einen Interruptvektor in 04h frei hält.
Bei den PIC16 meine ich gelesen zu haben, dass für das debuggen auf dem PIC der erste Befehl, also in 00h, ein NOP sein muss.

witkatz
13.01.2017, 19:31
Ich vermute, dass im Debugging-Mode ein Interrupt benötigt wird. Der für das debuggen erforderliche zusätzliche Code wird von der IDE automatisch erzeugt und eingefügt. Das obige Konstrukt stellt jedenfalls sicher, dass das Hauptprogramm Platz für einen Interruptvektor in 04h frei hält.

Ich glaube auch, dass hier so etwas im Gange war. Mit den OTP Chips war das Debuggen kniffelig, man konnte nur leere Zellen (0x3fff) mit Code beschreiben und bereits verwenden EPROM nur noch NOP (0) überschreiben. Auf der Katalogseite des PIC12C672 gibts dazu die Doku In-Circuit Serial Programming? (ICSP™) Guide (http://ww1.microchip.com/downloads/en/DeviceDoc/30277d.pdf).

Ich glaube nicht, dass der Programmierer die wichtigsten Vektoren des Chips aus Jux frei gelassen hat. Vielleicht hat er während der Entwicklung, je nach dem was auf dem Chip schon drauf war, manuell die Debug/Produktionsversionen des Code in freie Bereiche gebrannt und die alten Sprünge im Programm-EPROM mit NOP überschrieben. Davon sieht man in der Originalversion der ASM heute natürlich nichts mehr.

Mein Vorschlag wäre, das Projekt z.B. auf den von Microchip vorgeschlagenen Nachfolger PIC12F683 zu portieren. Mit Flash-Speicher hat man den OTP Hickhack nicht mehr.

theborg
14.01.2017, 17:51
Ich würde mir das auch angewöhnen, in dem beispiel fange ichab 0x00 an wegen einem vorgeschalteten Bootloder, die ersten pahr Adressen haben noch weitere Funktionen z.b. beim debuggen brauchst du zwei NOP direkt in den ersten Adressen, oder bei einigen Bootlodern müssen da Statusregister gelöscht werden dafür sind die Reserviert, die ISR Adresszeilen sind im Linker fest definiert, auch wieviele dafür genutzt werden können

PIC18F



org 0x000000 ; Starte Programm
nop
nop
goto init
org 0x000008 ; Interuptvector High
goto int
org 0x000018 ; Interuptvector Low

goto int
org 0x000028 ; Erste Routine auf Adresse 0x028


PIC16F



org 0x000000 ; Programanfang
nop ; NOP für Debugger
nop
goto go ; Springe zur Inialisirung
org 0x000004 ; Erste Rotine (go) auf Adresse 0x00005