Wat doet deze instructie precies MOV DPTR,#text

Hi Co's

Als je text wil sturen van je uC (mcs-51)naar je pc dan kan je dat vele manieren doen. Ik gebruikt deze code "MOV DPTR,#text" om de text te laden voordat ie naar de sbuf gaat. Ik gebruikt dit vaak. Maar wat doet deze code precies

MOV DPTR,#text

TEXT: DB " Have a nice day!!!",13,10,

Adres van TEXT gaat naar DPTR...
Het is trouwens wel handig als je in je post iets vermeld, zoals MCU type, enz...

Ik wil toch ietje specifieker;
DB vertaalt alle karakters naar ascii code bv de "Have" wordt dan 48h 41h 56h 45h...... maar dan wat? waar gaat al deze code?

Klinkt mij een beetje als een schoolvraag? Zoek eens in een datasheet oid naar de instructie lijst en wat die mov precies doet...

Die instructie laadt alleen maar het geheugenadres van label TEXT in DPTR. Dat is alles.

Verder zal je nog in een routine alle karakters moeten aflopen: karakter ophalen, versturen over een seriële poort, wachten tot alle bits serieel uitgeklokt zijn, de pointer ophogen en kijken of je alle bytes hebt gehad; zo niet, herhalen.

Op 26 november 2008 14:41:54 schreef Fuzzbass:
Die instructie laadt alleen maar het geheugenadres van label TEXT in DPTR. Dat is alles.

Dat zie ik ook, maar hoe dat gebeurdt wil ik weten. In de praktijk is het makkelijk om iets gewoon over te nemen. Maar beter is om het te begrijpen. De DPTR register is een register die meestal gebruikt wordt als een pointer. Dan laadt je een bepaalde addres bv erin om later weer te halen.
Maar hier wordt een label (Text) erin geladen. En achter de label wordt via de DB instuctie alles naar asci code vertaalt.
"Have a nice day!!" de "H" is 48h de "a" 41H dit zijn allemaal bytes. Als je deze code zoekt in de MCS-51 instructie set dan zal je deze niet vinden.

Verder zal je nog in een routine alle karakters moeten aflopen: karakter ophalen, versturen over een seriële poort, wachten tot alle bits serieel uitgeklokt zijn, de pointer ophogen en kijken of je alle bytes hebt gehad; zo niet, herhalen.

Dit is niet mijn probleem. Ik gebruikt deze code al jaren. En ik ben er ook zeker van dat velen dat dit code ook al jaren gebruiken zich nu ook afvragen... "wat doet dit code dan precies"

Dan moet je je eens verdiepen in hoe een assembler werkt, die regelt dat allemaal.

Het label wordt niet geladen, maar het adres dat door dat label aangewezen wordt. Een geheugenadres dus. DB is een assembler directive die zorgt dat de tekst die erachter staat als ASCII op het geheugenadres van het label gezet wordt.

Dan laadt je een bepaalde addres bv erin om later weer te halen.

Nee, het is zoals je eerder opmerkte gewoon een pointer. En daarbij doet het niet ter zake waar die naar toe wijst. (Een subroutinenaam is in dat opzicht hetzelfde als een label. Het is gewoon een 'placeholder' voor een adres)
Het heeft verder niks met het tonen van de tekst te maken. Dat doet de rest van de code door de karakters een voor een te versturen, door de pointer steeds op te hogen...

Op 26 november 2008 15:00:26 schreef Fuzzbass:
Dan moet je je eens verdiepen in hoe een assembler werkt, die regelt dat allemaal.

Het label wordt niet geladen, maar het adres dat door dat label aangewezen wordt. Een geheugenadres dus.

Dus zie je wel, deze code is dan een intelligente code. Dus als ik dit goed begrijp, laadt deze code de ascii-code op de address van de TEXT label in de program memory. Dus als ik dit schrijf DB " Hello World" ,13, 0
dan levert dit 13 gehuegen plaatsen in program memory

48h 45h 4Ch 4Ch 4Fh 20h 57h 4Fh 52h 4Ch 44h 0Dh 00h

[Bericht gewijzigd door uZion op (31%)]

Nee, je hebt het nog steeds mis. Lees heel het topic nog eens vijf keer van voor naar achter.

Lees eens goed wat 'indirecte adressering' is...

Op 26 november 2008 15:54:43 schreef Fuzzbass:
Nee, je hebt het nog steeds mis. Lees heel het topic nog eens vijf keer van voor naar achter.

Op 26 november 2008 15:00:26 schreef Fuzzbass:

Het label wordt niet geladen, maar het adres dat door dat label aangewezen wordt. Een geheugenadres dus. DB is een assembler directive die zorgt dat de tekst die erachter staat als ASCII op het geheugenadres van het label gezet wordt.

Hoezo dan weer mis?? Kijk wat jij zelfs hier heeft geschreven. Dat hebt ik ook gezegd.

Het wordt verwarrend, omdat je nu 2 verschillende vragen door elkaar stelt. Je begon met de vraag:

Wat doet "MOV DPTR,#text"

En halverwege het verhaal verandert het in:

Wat is "TEXT: DB " Have a nice day!!!",13,10,"

Dat zijn 2 verschillende zaken. De eerste geeft zoals gezegd een pointer, de tweede slaat gewoon databytes op die je aanlevert op het adres van een label.

TEXT is hier alleen een label, net zoals je meer labels hebt om bv naartoe te springen. DB wil zeggen (DataBytes geloof ik) dat er een reeks bytes volgen die geen code zijn. Puur constantes dus. Als je nu DPTR laadt met TEXT, dan vult de assember op de plaats van TEXT het adres in waar TEXT in de code staat, het adres van TEXT dus. Met andere woorden, DPTR wijst naar het het eerste byte (48h). Het einde van een string wordt vaak met een 0h afgesloten. Daaraan kan de routine die de tekst op het scherm gaat schrijven zien waar de string eindigt. 13h is een CR waarmee je naar de volgende regel springt.

Op 26 november 2008 19:11:20 schreef flipflop:
DPTR wijst naar het het eerste byte (48h)

Je zegt het goed "wijst" dus dat is indirect addressing.
Maar de address van de DPTR is geladen met de program counter address van "TEXT" in de code.
En een MOV DPTR,#TEXT laad de DPTR met de informatie dat op dat address is en dat is 48h. Dus de eerste address van de program counter waar TEXT in de code staat.
Iedereen nu wel eens???

Neeeee.... |:(

Lees nu eindelijk eens de datasheet. DPTR WORDT GELADEN MET DE WAARDE (= ADRES) VAN HET LABEL 'TEXT', niet met de data zelf. Daarom heet het ook een datapointer...

.DB (define byte), er bestaat ook een .DW (define word), is een compiler directive of pseudo-op en doet niets anders dan de data die er achter staat op de momentele positie van de instructie counter in het geheugen zetten.

Dat een string toevallig wordt omgezet in ascii is een voordeel van de gebruikte assembler. Als je na assembleren in de .lst file kijkt zie je de data staan zoals het in memory komt.

in plaats van de string kun je ook de hex, of decimale ascii waardes van de afzonderlijke letters zetten.

.DB "ABCD" is gelijk aan .DB 97,98,99,100 of .DB 61h,62h,63h,64h

Met de .ORG compiler directive kun je de momentele positie van de instructie counter beinvloeden....

.ORG 1000h
.DB 10,20,30

Op positie 1000h staat nu 10
op positie 1001h staat nu 20
op positie 1002h staat nu 30

Meestal wordt als laatste een 0 gezet zodat je hierop kunt testen, en zo het einde van de string weet.

.DB "Hello, world",13,10,0

Dit is dus de string met daarachter Carriage Return (13) en Line Feed (10) en een 0 om het einde te markeren.

Hieronder een stukje code hoe je van begin tot eind (0) door de string loopt en iets met elk karakter kunt doen (b.v. naar een lcd-print routine sturen). Op het moment dat ik 0 lees spring (JZ = Jump if accu Zero) ik naar het einde label (EXIT)


MOV     DPTR,#Prompt    ;pointer to data


_next:  CLR   A         ;clear accumulator
        MOVC  A,@A+DPTR ;laad teken waar pointer naar wijst in accu
        JZ    EXIT      ;bevat accu 0, dan exit

        doe hier iets met het teken in de accu

        INC   DPTR      ;verhoog pointer (volgende teken)
        SJMP  _next     ;doorloop lus nogmaals
EXIT:


Prompt: .DB "Hello, world",13,10,0

.DB .ORG en .DW kom je dus niet tegen in de instructie set van de MCS-51 family, maar wel in de handleiding van de assembler.

Op 26 november 2008 21:49:27 schreef Arco:
Neeeee.... |:(

Lees nu eindelijk eens de datasheet. DPTR WORDT GELADEN MET DE WAARDE (= ADRES) VAN HET LABEL 'TEXT', niet met de data zelf. Daarom heet het ook een datapointer...

Sorry sorry, ik had het wel goed bedoeld maar fout geschreven.

Op 26 november 2008 15:33:24 schreef uZion:
[...]
Dus zie je wel, deze code is dan een intelligente code. Dus als ik dit goed begrijp, laadt deze code de ascii-code op de address van de TEXT label in de program memory. Dus als ik dit schrijf DB " Hello World" ,13, 0
dan levert dit 13 gehuegen plaatsen in program memory

48h 45h 4Ch 4Ch 4Fh 20h 57h 4Fh 52h 4Ch 44h 0Dh 00h

Schimanski zegt ook het zelfde kijkt eens:

Op 26 november 2008 22:02:37 schreef Schimanski:
Met de .ORG compiler directive kun je de momentele positie van de instructie counter beinvloeden....

.ORG 1000h
.DB 10,20,30

Op positie 1000h staat nu 10
op positie 1001h staat nu 20
op positie 1002h staat nu 30

Meestal wordt als laatste een 0 gezet zodat je hierop kunt testen, en zo het einde van de string weet.

.DB "Hello, world",13,10,0

Dat klopt wel, maar er is niets intelligents aan de code. DB laadt gewoon de betreffende byte met de waarde die je aanlevert. 1 decimaal, 0x0F hex, en 'A' geven waardes van reps. 1, 15, en 65.


MOV DPTR,#text

ORG 0x1000
TEXT: DB " Have a nce day!!!",13,10,   

laadt DPTR dus met 0x1000, niet met 'H'...

Zullen we maar verder gaan met dit topic als de heer uZion de datasheet, en met name het deel over indirecte adressering, gelezen heeft? Dit heeft anders totaal geen zin.

Juistem... DPTR bevat een adres, en op dat adres staat een waarde (b.v. "H")

Eerst laadt je DPTR met het adres van (label) Prompt:


MOV     DPTR,#Prompt    ;pointer to data

Daarna laadt je de accu met het getal (teken) wat op dat adres staat


MOVC  A,@A+DPTR 

Vergelijk het geheugen met een grote ladenkast. DPTR kan alleen maar naar de dichte laatjes wijzen, met MOVC A,@A+DPTR doe je het laatje open en haal je de inhoud van het laatje naar de accu

Op 26 november 2008 23:41:16 schreef Fuzzbass:
Zullen we maar verder gaan met dit topic als de heer uZion de datasheet, en met name het deel over indirecte adressering, gelezen heeft? Dit heeft anders totaal geen zin.

Nee maar het is nu duidelijk voor mij! Wij zijn nu allemaal eens met elkaar!! Many thanks guys