come viene tradotta l'istruzione PRINT in asm?

Sezione dedicata ai Microcontrollori e ai Sistemi Embedded

come viene tradotta l'istruzione PRINT in asm?

Postby Regedit » 27 Oct 2012, 15:15

scusate,
la mia è una semplice curiosità
io sto cercando di scrivere dei semplici programmini per i micro avr in particolare gli atmel mega.
ma ho una curiosità che mi assilla, ad esempio, quando io scrivo l'istruzione in bascom "PRINT" oppure "INPUT" questa come viene tradotta dal compilatore?
cioè quali sono esattamente le istruzioni assembly che costituiscono questa istruzione?

quali sono le strade per poter studiare in modo più affrofondito cio?
non so se sono stato chiaro.
grazie
Regedit
 
Posts: 16
Joined: 05 Jan 2012, 21:04

Re: come viene tradotta l'istruzione PRINT in asm?

Postby legacy » 27 Oct 2012, 20:03

un compilatore, C o Basic, traduce "print" o "input" con una chiamata a funzione, alle funzioni "print" o "input"
mettendo prima sullo stack cio' a cui loro serve, il numero di parametri, e i parametri stessi

dal chiamente al chiamto le istruzioni assembly che si incontrano
- passano i parametri (sullo stack) alla subroutine che sta per essere chiamata
- la invocano con una jump to subroutine
- nella subroutine print ci trovi istruzioni assembly per recuperare i parametri dallo stack
- interpretarli per formattare l'output
- spedirle l'output byte a byte sulla buffer di uscita della seriale
- concluso il tutto, fare return from subroutine
- smantellare i parametri messi sullo stack

questo l'iter, input si comporta analogamenti


edit:
i dettagli precisi, le istruzioni precise le ottieni disassemblando bascom
non tutto bascom, solo le subroutine "print" e "input"
basta capire a che indirizzo sono mappate
Last edited by legacy on 28 Oct 2012, 01:16, edited 13 times in total.
legacy
 
Posts: 862
Joined: 12 Mar 2012, 11:30

Re: come viene tradotta l'istruzione PRINT in asm?

Postby Regedit » 27 Oct 2012, 20:38

grazie legacy per la tua descrizione su come vengono gestite le funzioni, questo bene o male lo sapevo di già.

la mia domanda era diversa e ben chiara:

mi interessa sapere da quali istruzioni assembly è costituita l'istruzione "print" e "input" del bascom.

ciao
Regedit
 
Posts: 16
Joined: 05 Jan 2012, 21:04

Re: come viene tradotta l'istruzione PRINT in asm?

Postby flz47655 » 28 Oct 2012, 04:15

Ciao,
Usando questo codice dove ho inserito due istruzioni solamente assembly per capire l'inizio della funzione PRINT

Code: Select all
$regfile = "m644pdef.dat"
$crystal = 8000000

Main:
Do
   ADD R2,R4
   ADD R2,R4
   Print "Ciao"
Loop
End

ho ottenuto:

Code: Select all
; ... codice di inizializzazione, etc..
L5:   ADD R2,R4
   ADD R2,R4
   LDI ZL,$1E   ; Da qui in poi inizia la funzione print
   LDI ZH,$01
   CALL L3
   CALL L4
   JMP L5
   BCLR 7
L6:   RJMP L6
L3:   CALL L7
   MOV R24,R0
   BREQ L8
   RCALL L9
   RJMP L3
L8:   RET
L4:   LDI R24,$0D
   RCALL L9
   LDI R24,$0A
L9:   LDS R0,$00C0
   SBRS R0,5
   RJMP L9
   STS $00C6,R24
   RET
L10:   SBIW ZH:ZL,1
   BRNE L10
   RET
   BSET 6
   BLD R6,2
   RET
   BCLR 6
   BLD R6,2
   RET
L7:   LPM


Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: come viene tradotta l'istruzione PRINT in asm?

Postby deluca » 28 Oct 2012, 12:16

flz, purtroppo devo darti una cattiva notizia....

il disassemblaggio di un file.HEX intanto è la peggiore strada da percorrere quando si vuole capire come è stata realizzata una funzione o una istruzione.
in molti casi il reverse engineering non porta a nulla anzi ti offusca le idee.
l'istruzione "Print" utilizza dei registri della uart in particolare il "Control and Status Register A - UCSRA" e l' "Uart data register - UDR"
- dove sono nel codice che hai disassemblato?
- dove si trova inoltre la costante "CIAO" ?

come vedi il disassemblatore che hai utilizzato non capisce la struttura del codice sorgente e quindi interpreta coppe x mazze.
non solo, traduce anche "CIAO" in istruzioni sballando tutto il codice assembly a partire proprio da li.

mi dispiace dirlo, ma secondo me tutto questo è il frutto di -------------- arduino !!!
programmare usando linguaggi ad alto livello, senza sapere cosa succede a livello registri cpu porta proprio a questo:
difficoltà nella interpretazione e ottimizzazione di un codice a basso livello.

per darvi un'idea, vi mostro quale dovrebbe essere il codice in assembly della istruzione "print":

Code: Select all
;codice assembly della istruzione "Print"
;autore: Giovanni De Luca
;
.include   "C:\AVRASM\inc\m8def.inc"
;
      .DSEG      
      .CSEG
.ORG   0

,----qui inizializziamo la ram e il baud rate della uart con i reg UBRR
_Reset:
      ldi      yl,Low(RAMEND)
      out      SPL,yl
      ldi      yh,high(RAMEND)
      out      SPL+1,yh
      sbiw   yl,32
      ldi      zl,0x18
      out      UCSRB,zl
      ldi      zh,high(51)
      ldi      zl,Low(51)
      out      UBRRL,zl
      out      UBRRH,zh

;-------Print "CIAO"--
      ldi      zl,Low(S000*2)
      ldi      zh,high(S000*2)
      call   _PSc
      call   _PCL

; ------String constants:
S000:   .db   "CIAO", 0


;------- Print String constants
_PSc:   lpm
      tst      r0
      breq   _PSc1
      mov      r24,r0
      rcall   _Pch
      adiw   zl,1
      rjmp   _PSc
_Psc1:   ret

;------ Print Cr, Lf & char
_PCL:   ldi      r24,0x0d
      rcall   _Pch
      ldi      r24,0x0a
_Pch:   sbis   UCSRA,5
      rjmp   _Pch
      out      UDR,r24
      ret



di seguito il codice per "INPUT" di una stringa
Code: Select all
;
.include   "C:\AVRASM\inc\m8def.inc"
;
      .DSEG
a:                  .Byte    21
      
      .CSEG
.ORG   0

_Reset:
      ldi      yl,Low(RAMEND)
      out      SPL,yl
      ldi      yh,high(RAMEND)
      out      SPL+1,yh
      sbiw   yl,32
      ldi      zl,0x18
      out      UCSRB,zl
      ldi      zh,high(51)
      ldi      zl,Low(51)
      out      UBRRL,zl
      out      UBRRH,zh

;-------Input a
      ldi      r25,20
      ldi      xl,Low(a)
      ldi      xh,high(a)
      call   _InSt9

;-------GetChar
_GetCh:   sbis   UCSRA,0x07
      rjmp   _GetCh
      in      zl,UDR
      ret

;------ Input
_Input:   ldi      xl,Low(RAMEND - 32)
      ldi      xh,high(RAMEND - 32)
      ldi      r25,0x06
_InSt9:   rcall   _GetCh
      cpi      zl,0x0a
      breq   _InEnd
      cpi      zl,0x0d
      breq   _InSt9
      cpi      zl,0x08
      breq   _InBck
      tst      r25
      breq   _InSt9
      st      X+,zl
      dec      r25
      rjmp   _InSt9
_InEnd:   clr      zl
      st      X,zl
      ret
_InBck:   inc      r25
      sbiw   xl,0x01
      rjmp   _InSt9



ciao
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: come viene tradotta l'istruzione PRINT in asm?

Postby flz47655 » 28 Oct 2012, 12:55

Pensavo che fosse interessato all'assembly AVR per curiosità (tanto per avere un'idea di come'è la sintassi Assembly) e non per scopi pratici o per iniziare a studiarlo.. analizzare la funzione PRINT non sarebbe un buon inizio. Deve iniziare dalle basi.

Purtroppo aver usato il primo disassemblatore trovato con Google non è stata una buona idea.. a dir la verità non ho neanche controllato il risultato ottenuto che potrebbe anche essere errato ma visto che pensavo che era per avere un'idea della sintassi l'ho postato.

Mi ero posto delle domande analoghe a quelle che mi ha segnalato e avevo dedotto che:

- i registri UCSRA e UDR sono i vari RXX che il disassemblatore non ha trasformato in mnemomici più comprensibili (non ho controllato ma mi ero dato una possibile spiegazione in questo modo)

- la costante CIAO si trova in una sezione dati inclusa dell'eseguibile che viene in qualche modo richiamata ma che non è inclusa nel testo restituito dal disassemblatore

Il codice che hai postato è sicuramente più utile a capirci qualcosa

Grazie
Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: come viene tradotta l'istruzione PRINT in asm?

Postby legacy » 28 Oct 2012, 13:39

deluca wrote:il disassemblaggio di un file.HEX intanto è la peggiore strada da percorrere quando si vuole capire come è stata realizzata una funzione o una istruzione.
in molti casi il reverse engineering non porta a nulla anzi ti offusca le idee.
ciao


pero' a volte e' la sola strada, sopratutto se non hai i sorgenti
reversing for hack :lol:
Last edited by legacy on 28 Oct 2012, 17:26, edited 7 times in total.
legacy
 
Posts: 862
Joined: 12 Mar 2012, 11:30

Re: come viene tradotta l'istruzione PRINT in asm?

Postby flz47655 » 28 Oct 2012, 13:44

ma ho una curiosità che mi assilla, ad esempio, quando io scrivo l'istruzione in bascom "PRINT" oppure "INPUT" questa come viene tradotta dal compilatore?


C'è da dire anche che è stato chiesto proprio come viene tradotta dal compilatore l'istruzione PRINT del bascom e non una equivalente che comunque ha maggiore valenza didattica e per la quale sicuramente regedit ne trarrà maggiori informazioni.

Ad ogni modo colgo l'occasione per segnalare che nel datasheet al capitolo USART sono presenti esempi sia in codice C sia Assembly nel caso volesse approfondire la questione.

Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: come viene tradotta l'istruzione PRINT in asm?

Postby flz47655 » 28 Oct 2012, 14:42

Nel copia incolla avevo perso una parte finale (includo anche gli op-code) che posto per il semplice fatto che come giustamente aveva fatto notare Giovanni i byte della stringa "Ciao" non erano presenti, io avevo supposto che erano in una sezione dati.

Questa fantomatica sezione effettivamente c'è ma il decompilatore utilizzato (uno dei primi trovati con Google) non ha saputo discriminarla dalle istruzioni, infatti nella parte persa alla fine dal copia-incolla:

Code: Select all
00008B  95C8    L7:   LPM
00008C  9631       ADIW ZH:ZL,1
00008D  2000       TST R0
00008E  9508       RET
00008F  6943       ORI R20,$93
000090  6F61       ORI R22,$F1
000091  0000       NOP


E' chiaramente possibile vedere che alla fine dell'eseguibile sono presenti i byte proprio equivalenti alla stringa "Ciao" 43-69-61-6F (tralasciando l'ordinamento utilizzato dal Micro i byte sono quelli) e non sono interpretati come le istruzioni ORI che non centrerebbero nulla.

L'istruzione n. 00008F (143 in decimale) equivarrebbe all'indirizzo 11E (286 in decimale) visto che ogni istruzione è 2 byte e..
Guarda un pò il codice disassemblato alle prime istruzioni che avevo pubblicato:

Code: Select all
LDI ZL,$1E
LDI ZH,$01


Sembra proprio caricare qualcosa dall'indirizzo 11E che contiene "Ciao"
Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: come viene tradotta l'istruzione PRINT in asm?

Postby deluca » 28 Oct 2012, 14:50

@flz,
le istruzioni assembly per PRINT e INPUT mostrate sopra non sono equivalenti, sono proprio quelle che ho tirato giù per il compilatore citato :)

purtroppo, difficilmente potrai trovare un disassemblatore capace di discriminare le famigerate "stringhe" puntate.

appena si presentano, tutto il resto del codice diventa indecifrabile.
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: come viene tradotta l'istruzione PRINT in asm?

Postby flz47655 » 28 Oct 2012, 15:23

In questo caso il compilatore le aveva proprio messe alla fine del programma :)
Non so se il resto del codice diventa indecifrabile però se il compilatore riesce a tenere una sorta di allineamento.. ma non voglio investigare oltre per il momento.

Non ho purtroppo ancora avuto tempo per approfondire l'AVR a livello di registri col C o con l'Assembly (avevo fatto qualcosa di Assembly x86). Speriamo solo che Arduino non mi rincitrullisca troppo :D

Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16


Return to Microcontrollori e microprocessori

Who is online

Users browsing this forum: No registered users and 12 guests