Forum: Compiler & IDEs Gnu Assembler: Wie Konstante ausgeben?


von Salat (Gast)


Lesenswert?

Hallo.

Eigentlich eine ganz einfache Aufgabe:

MYVAR = 12345

.error "Hier steht MYVAR."

Wie macht man es richtig?

: Verschoben durch Moderator
von Nop (Gast)


Lesenswert?

Im Inline-Assembler geht das auch so, wie Du das hast. Sonst kannst Du 
es ja auch so versuchen:
1
.equ MYVAR,12345

Siehe auch hier: 
https://community.arm.com/processors/b/blog/posts/useful-assembler-directives-and-macros-for-the-gnu-assembler

von Salat (Gast)


Lesenswert?

In deinem Link habe ich leider nichts dazu gefunden. Es geht wie gesagt 
darum, dass man eine berechnete Konstante einfach mal ausgibt. Manchmal 
will man ja wissen, was drin steht, wenn man die Konstante aus anderen 
Konstanten berechnet. Sowas banales müsste doch möglich sein?

von Nop (Gast)


Lesenswert?

Salat schrieb:
> In deinem Link habe ich leider nichts dazu gefunden.

Augen auf oder Volltextsuche nach ".set".

von Thomas E. (picalic)


Lesenswert?

Nop schrieb:
> Augen auf oder Volltextsuche nach ".set".

Selber mal die Augen aufmachen und lesen, was der TO will:

Salat schrieb:
> Es geht wie gesagt
> darum, dass man eine berechnete Konstante einfach mal ausgibt.

Einen Konstanten Wert zu definieren (ob mit .set, =, .equ oder sonstwas) 
scheint nicht sein Problem zu sein.

von R. M. (Gast)


Lesenswert?

Ich glaube, dem TE geht es weniger um die Definition der Konstante, als 
viel mehr, die Ausgabe des Wertes auf die Konsole, während der 
Assemblierung.

von Nop (Gast)


Lesenswert?

Man kann Strings während der Assemblierung ausgeben mit
1
.print "My little string"

Zahlen gehen damit allerdings nicht, das ist kein printf. Aber man kann 
sich natürlich was basteln, wenn man nur sehen will, ob die Konstante an 
der Stelle den erwarteten Wert hat, indem man .if (bzw. .ifeq) .print 
.endif nimmt.

Hier noch ein cheat sheet: 
http://www.coranac.com/files/gba/re-ejected-gasref.pdf

von symboltable (Gast)


Lesenswert?

Schau mal in die Symboltabelle:
1
$ echo ".equ MYVAR, 1+1024" | as -va | grep MYVAR
2
3
GNU assembler version 2.28 (arm-linux-gnueabihf) using BFD version (GNU Binutils for Raspbian) 2.28
4
   1                .equ MYVAR,1+1024
5
    {standard input}:1      *ABS*:00000401 MYVAR

von Salat (Gast)


Lesenswert?

Also das resultierende Binary parsen finde ich jetzt nicht wirklich 
praktisch. Ich kann mir beim besten Willen nicht vorstellen, dass kein 
Programmierer jemals Variablen, oder nennen wir sie von mir aus Symbole, 
als Fehlermeldung ausgeben wollte.

von S. R. (svenska)


Lesenswert?

Salat schrieb:
> Ich kann mir beim besten Willen nicht vorstellen, dass kein
> Programmierer jemals Variablen, oder nennen wir sie von mir aus Symbole,
> als Fehlermeldung ausgeben wollte.

Zur Assemblerzeit existieren keine Variablen, sondern nur konstante 
Werte. Und deren Wert ist - überraschenderweise - zur Assemblerzeit 
konstant.

Bei solchen Direktiven geht es darum, unerwartete Abweichungen zu 
erkennen, der eigentliche Wert ist selten wichtig.

von Salat (Gast)


Lesenswert?

Beim Debuggen würde so eine Ausgabe aber ungemein helfen. Vor allem, 
wenn die Konstanten aus anderen Konstanten berechnet wurden, man den 
Wert also nicht mal eben so auslesen kann..

Also... gibts eine Art printf? Kann auch gerne ein banales sein. Ich 
will nur eine Konstante ausgeben.

Beitrag #5511256 wurde von einem Moderator gelöscht.
von Markus F. (mfro)


Lesenswert?

Salat schrieb:
> Also... gibts eine Art printf? Kann auch gerne ein banales sein. Ich
> will nur eine Konstante ausgeben.

Nicht daß ich wüsste.

Was hält dich davon ab, einfach mit '-a' ein Listing auszugeben?
Da sollte drinstehen, was Du wissen willst.

von Reiner O. (elux)


Lesenswert?

Salat schrieb:

> wenn die Konstanten aus anderen Konstanten berechnet wurden

Warum hießen Konstanten noch mal so?

Wenn ich aus Debuggründen in Assembler den Inhalt eines Registers wissen 
will, ist es ein Zweizeiler, ungefähr so:
1
...
2
mov    TEMP_0,wichtiger_Registerinhalt
3
    rcall  uart_send_byte
4
...

irgendwo habe ich so oder so eine Ausgabeschleife:
1
**********************************
2
; Sub: Sendet ein Byte aus TEMP_0 über UART (USB)
3
; Parameter:  TEMP_0 Datenbyte
4
; Return:    -
5
; Scratch-Reg:  -
6
;**************************************************************************
7
8
uart_send_byte:
9
  push  TEMP_1    
10
uart_send_byte_1:
11
  lds  TEMP_1, UCSR0A
12
  sbrs    TEMP_1,UDRE0                ;SendRegister leer ?
13
        rjmp    uart_send_byte_1          ; nein
14
        sts     UDR0,TEMP_0
15
  pop  TEMP_1
16
        ret

Ist zwar kein GNU-Assembler, aber da wird es vermutlich auch nicht 
anders sein.

MfG
Elux

von Markus F. (mfro)


Lesenswert?

Reiner O. schrieb:
> Wenn ich aus Debuggründen in Assembler den Inhalt eines Registers wissen
> will, ist es ein Zweizeiler, ungefähr so:

Das schön, aber bloß nicht das, was der TO wissen wollte.

Ich habe ihn jedenfalls so verstanden, dass er während des 
Assembler-Laufs den Wert einer Konstanten ausgeben will.

von Carsten R. (kaffeetante)


Lesenswert?

.error
.message
.warning

erwarten unmittelbar einen String und weder ein Symbol stattdessen, noch 
weitere Parameter. Damit geht es also nicht. Und das sind die Direktiven 
die Meldungen ausgeben.

Ich würde es daher als Konstante im Flash hinterlegen und mit dem Editor 
im Endergebnis (.hex)kontrollieren. Damit man es findet, kann man einen 
entsprechendeen String definieren und unmittelbar voranstellen, z.B. 
"Kontrolliere mich!".

Das ist zwar etwas unschön, aber die Präprozessordirektiven sind in der 
Doku aufgelistet. Und da gibt es nicht so viele Benachrichtigungsmittel.

Alternativ kann man den Wert mit Formeln prüfen lassen und dann abhängig 
vom Ergebnis bedingt unterschiedliche Strings ausgeben, so wie es im 
ASM-Tutorial bei der Baudratenberechnung vorgeführt wurde.

https://www.mikrocontroller.net/articles/AVR-Tutorial:_UART

Das ist abr keine direkte Ausgabe des Ergebnisses.

von symboltable (Gast)


Lesenswert?

@ Salat : Hast Du Dir so etwas wie hier unten vorgestellt?
1
/*  file: printvar.S
2
3
  Macros zum Drucken auf STDOUT während der Assemblierung.
4
  Da .print einen String als Parameter erwartet, muss
5
  dieser mittels eines Helfermacros konstruiert werden.
6
*/
7
8
.macro printhelper t, w
9
/*  Aneinanderfügen der Teilstrings t und w */
10
        .print "\t \w"
11
.endm
12
13
.macro printvar text, value
14
/*  Mit dem %-Zeichen value evaluieren.
15
  Zur Aktivierung dieser Funktion wird .altmacro benötigt! */
16
.altmacro
17
        printhelper \text, %\value
18
.endm
19
20
.equ MYVAR, 1024+1
21
22
printvar "MYVAR=", MYVAR
23
.end


1
$ as -v printvar.S 
2
GNU assembler version 2.28 (arm-linux-gnueabihf) using BFD version (GNU Binutils for Raspbian) 2.28
3
MYVAR= 1025

Das Beispiel bei stackoveflow war für die Programmierung sehr hilfreich:
https://stackoverflow.com/questions/26813510/expression-in-gcc-arm-assembly-macro


73

von S. R. (svenska)


Lesenswert?

Salat schrieb:
> Beim Debuggen würde so eine Ausgabe aber ungemein helfen.

Wenn du an der Stelle ein Problem hast, dann ist vermutlich woanders 
bereits was schiefgelaufen. Wie gesagt, der Wert deiner Konstanten steht 
in der Symboltabelle drin.

Salat schrieb:
> Also... gibts eine Art printf?

Ein printf kann es prinzipbedingt nicht geben, weil der Assembler (bzw. 
dessen Präprozessor) keine Datentypen kennt. Alles andere sind ziemliche 
Hacks, aber die wurden bereits genannt.

von Salat (Gast)


Lesenswert?

@symboltable

Funktioniert! Zumindest nach einer kleinen Änderung. Vielen Dank für die 
Hilfe!


.macro printhelper t1, t2
        .print "\t1\t2"
.endm
.macro printvar text, value
.altmacro
        printhelper \text, %\value
.noaltmacro
.endm

printvar "myvar lautet ", MYVAR


Man kann das Macro nicht in einer externen Datei speichern und via 
include einbauen. ka wieso. Aber ganz ehrlich... der gas wäre eh ein 
Kandidat zum komplett neuschreiben.

von Markus F. (mfro)


Lesenswert?

Schlau.

Kannte ich bislang nicht, danke!

Beitrag #5512474 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.