PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Compilieren in die andere RIchtung?



Memby
18.11.2005, 05:00
Hallo,

habe ein schönes Programm mit Bascom geschrieben und in den Atmega8 geladen. Leider mein ganzes Verzeichniss mit dem Programm auf meiner Festplatte gelöscht. (Unwiederruflich!).

Meine Frage: Das Programm bekomme ich ja ohne Probleme aus dem Flasch, mit Bascom oder auch Pony Prog. Doch kann ich jetzt das Programm von .hex nach .bas oder .c oder ähnliches kompilieren,
da ich es noch verändern möchte.

Wenn Nein, warum und was passiert den beim Compilieren genau?

MfG
memby

super_castle
18.11.2005, 08:45
Schau mal unter Decompiler für Hex-Dateien für AVR.
Dann kannst du dieses wenigstens mit AVR-Studio bearbeiten und evtl die ASM-Befehle zurückverfolgen zum Umsetzen in Basic.
Nach Bas und C kannst du es zur Zeit nicht zurückwandeln aber in ASMSource-Code.

Castle

Marco78
18.11.2005, 19:29
Nein.

Wenn Nein, warum und was passiert den beim Compilieren genau?
Weil der Code von Bascom in Assemblerbefehle "umgewandelt" wird. Wie schon gesagt wurde, kannst du denn Code wiederherstellen. Aber um es in Basic zu übersetzen fehlt es an Programmen. Schon alleine deshalb, weil es zu aufwendig wäre sowas umzuwandelt.
Vielleicht ein verständliches Beispiel:
Als Rechenergebnis hast du eine 5. Wie lautet die Rechnung dazu?

super_castle
18.11.2005, 20:40
Es ist machbar, das Zurückumwandeln in Bascom.
Das Programm kann aber nur der Bascomhersteller erstellen, weil er den Weg kennt. Es ist genauso einfach, als wenn man ein abgewickelten Bindfaden wieder aufwickeln tut. Nichts ist unmöglich.
Nur die Nachfrage für solch ein Programm ist zu gering.

Bei "C" ginge es nicht, weil der C-Compiler Teile wegoptimieren kann. Und beim Rückwärtsfahren, fehlen dann die Optimierungen in der Hexdatei und hat dort Luftlöcher.

Castle

Marco78
18.11.2005, 21:05
Ich habe ja auch nicht gesagt, das es nicht geht!
Es gibt halt (noch) kein Programm, was das kann. Weil es kein Bedarf dafür gibt. Soetwas zu programmieren ist schon fast aufwendiger als Bascom selbst zu programmieren.

Das Programm zum Rückwandeln bräuchte dann das was bei meinem Beispiel (Rechnung mit 5) auch nötig wäre. Zwei Vorgaben wie man zur Lösung kommt.

Um es deutlich zu sagen. So ein Programm gibt es (sehr höchst wahrscheinlich) nicht. Falls doch wäre das hier bestimmt schonmal aufgetaucht.
Um dein Programm zu ändern musst du Assembler lernen. Was man ja in der Regel nicht vor hat(te) wenn man (wie ich auch) sich für Bascom entschieden hat.
Selbst wenn du es lernst, fehlen im Code einige Kommentare, die das verstehen leichter machen würden. Heute ASM lernen und morgen schon den Code ändern geht nicht einfach so.

super_castle
18.11.2005, 21:27
Um mit Bascom meine Flashcard anzusprechen, musste ich ASM lernen.
Sonst hätte ich es nicht geschafft, meine 128MB mit Bascom anzusprechen.
Ich musste die "Lib" anpassen, sonst ging es nicht.
Es macht jetzt so einen riesen Spass, die "Lib" für Bascom mit ASM zu schreiben. Auch eine "Lib" für ein grafisches Display (256x128) habe ich umgeschrieben in ASM.

Castle



; CF-Register addresses

.equ Data_Reg = &H00
.equ Error_Reg = &H01
.equ Feature_Reg = &H01
.equ Sec_Cnt_Reg = &H02
.equ Sec_Num_Reg = &H03
.equ Cyl_Lo_Reg = &H04
.equ Cyl_Hi_Reg = &H05
.equ Head_Reg = &H06
.equ Status_Reg = &H07
.equ Command_Reg = &H07


; Commands for Compact Flash Card

.equ CF_Identify = &HEC
.equ CF_Write_Sec = &H30
.equ CF_Read_Sec = &H20


;------------------------------------------------------------------------------
[_DriveGetIdentity]
$EXTERNAL _CF_Write_Reg
; Read Identity Info from the CF-Card
_DriveGetIdentity:
ldi r21, 1 ; 512 Bytes = 1 Sector to read
ldi r23, CF_Identify ; Command for Card identity
rcall _CF_Write_CommandReg ; send to card
rjmp _CF_Read_Sector_LBASet ; Read Info to SRAM (mit return)
[End]



[_CF_Check_Ready]
; Pin CF_Rdy is Low at Ready
_CF_Check_Ready:
* sbis CF_Control_In , CF_Rdy ; no timeout check
rjmp _CF_Check_Ready
Ret
[END]



[_CF_Write]
$EXTERNAL _CF_Check_Ready
; give a pulse to WE to force Compactflash Card to read Data
; Registeraddress (A0-A2) and Data (D0-D7) must be set
_CF_Write:
rcall _CF_Check_ready
* cbi CF_Control_Out , CF_WE ; WE Line to Low
; Pulse is for Crystal 16 MHz, Approximitly 1 NOP for 2 MHz
; and can be reduced for slower CPU
nop
nop
nop
* #IF _XTAL > 6000000
nop
nop
nop
* #ENDIF
* #IF _XTAL > 12000000
nop
nop
* #ENDIF
* sbi CF_Control_Out , CF_WE ; WE Line to High
ret
[END]



[_CF_Read]
$EXTERNAL _CF_Check_Ready
; Read 1 Byte from the CF
; Register address must be set.
_CF_Read:
rcall _CF_Check_Ready
ldi _temp1, &H00 ; change data-port to Input
* out Cf_Data_DDR , _temp1
* cbi CF_Control_out , CF_OE ; OE Line to Low
nop
nop
nop
* #IF _XTAL > 6000000
nop
nop
nop
* #ENDIF
* #IF _XTAL > 12000000
nop
nop
* #ENDIF
* in r23 , CF_Data_in ; Read Byte
* sbi CF_Control_Out , CF_OE ; OE - Line to High
ldi _temp1, &HFF ; change Data-port back to OUTPUT
* out CF_Data_DDR , _temp1
ret
[END]


[_CF_Set_RegAddr]
; Set register address, and leave pins 3 - 7 unchanged
; two entry-points to routine
; 1: CF_Set_RegAddr: Register address must passed in r22
; 2: CF_Set_RegAddr23: register address is Data
_CF_Set_RegAddr23:
ldi r22, Data_Reg
_CF_Set_RegAddr:
* in _temp1 , CF_Addr_Out ; get current output at Port
andi _temp1, &B11111000 ; CF-Address-bits masked out
or _temp1, r22 ; add CF-Address with OR
* out CF_Addr_Out , _temp1
ret
[End]



[_DriveReadSector]
$EXTERNAL _CF_Set_CntLBA , _CF_Write_Reg , _CF_Read
; Read Sector(s) from CF-Card to SRAM
; Entry with following parameters set:
; Register r21: Count of Sector(s) to transfer
; Register X: Pointer to Sectornumber (LONG)
; Register Z: SRAM-Address, where the data to transfer
_DriveReadSector:
ldi r21, 1 ; fixed to 1 sector to read
rcall _CF_Set_CntLBA ; LBA-Sector to CF
ldi r23, CF_Read_Sec ; read command
rcall _CF_Write_CommandReg ; to Compactflash
_CF_Read_Sector_LBASet:
rcall _CF_Set_RegAddr23 ; turn register-address to data
clr r20 ; Low-Byte of Byte-Count always zero
lsl r21 ; Change Sector-Count to HighByte of Transferlenght
_CF_Read_Sector1:
rcall _CF_Read ; read 1 Byte
st z+, r23
dec r20
brne _CF_READ_SECTOR1
dec r21
brne _CF_READ_SECTOR1 ; all bytes read?
clr r25 ; set default no error
clc
Ret
[END]



[_DriveWriteSector]
$EXTERNAL _CF_Set_CntLBA , _CF_Write_Reg
; write Sector(s) to CF-Card
; Entry with following parameter set:
; Register r21: Count of sector(s) to transfer
; Register X: Pointer to Sectornumber (LONG)
; Register Z: SRAM-Address, at which Data to transfer starts
_DriveWriteSector:
ldi r21, 1 ; fixed to 1 sector to write
rcall _CF_Set_CntLBA ; LBA-Sector to CF
ldi r23, CF_Write_Sec ; write command
rcall _CF_Write_CommandReg ; to compactflash
_CF_Write_Sector_LBASet:
rcall _CF_Set_RegAddr23 ; turn register-address to data
clr r20 ; Low-Byte of Byte-Count alwas zero
lsl r21 ; Change Sector-Count to HighByte of Transferlenght
_CF_Write_Sector1:
ld r23, z+
* out CF_Data_out , r23 ; Byte to data port
rcall _CF_Write ; force CF to read byte
dec r20
brne _CF_Write_SECTOR1
dec r21
brne _CF_Write_SECTOR1 ; last byte written?
clr r25 ; set default no error
clc
Ret
[END]



[_CF_Write_Reg]
$EXTERNAL _CF_Set_RegAddr , _CF_Write
;------------------------------------------------------------------------------
; write a value to a specified register address, value is passed in r23
; two different entry points
; 1: CF_Write_CommandReg: write value to command-register (default)
; 2: CF_Write_Reg: Register passed in r22
_CF_Write_CommandReg:
ldi r22, Command_Reg ; Default register: Command
_CF_Write_Reg:
* out CF_Data_out , r23 ; set data to data port
rcall _CF_Set_RegAddr ; set register address
rjmp _CF_Write ; force CF to accept register and data
[End]



[_CF_Set_CntLBA]
$EXTERNAL _CF_Write_Reg
; Write count of sector(s) (read or write) and Sectornumber (LBA) to CF-Card
; following parameter must be set:
; Register CF_SectorCount: Count of Sector(s) (max &7F)
; Register X: Pointer to sectornumber
;
_CF_Set_CntLBA:
ldi r22, Sec_Cnt_Reg ; Start with Sector-Count Register in CF (2)
mov r23, r21 ; prepare for output
rjmp _CF_Set_LBA2
_CF_Set_LBA1:
ld r23, X+ ; load next byte of sectornumber
_CF_Set_LBA2:
rcall _CF_Write_Reg ; set register-address
inc r22 ; set to next register address
cpi r22, 6
brmi _CF_Set_LBA1 ; Reg. 6 reached? (LBA/Disk/Header)
ld r23, X+ ; need special handling
andi r23, &B00001111 ; mask upper nibble (LBA-Sign and drive)
ori r23, &HE0 ; set to LBA
rjmp _CF_Write_Reg ; write to CF; incl Ret
[END]



[_DriveInit]
$EXTERNAL _DriveReset
; Setup the pins needed for the CF-Card
_DriveInit:
; Data port to OUTPUT
ldi _temp1, &H00 ; all Data pins to low
* out CF_Data_Out , _temp1

ldi _temp1, &HFF
* Out CF_Data_DDR , _temp1 ; Data pins to output

; Controlport: prepare 6 pins, leave other two unchanged
* in _temp1 , CF_Control_Out ;
* andi _temp1 , CF_Control_Dir_Mask ;
* ori _temp1 , CF_Control_Init
* Out CF_Control_Out , _temp1

* in _temp1 , CF_Control_DDR ; read direction of pins at control port
* andi _temp1 , CF_Control_Dir_Mask ; mask out used pins
* ori _temp1 , CF_Control_Direction ; set direction in and Out
* Out CF_Control_DDR , _temp1 ; set new direction configuration

; Address port: attention: adjust if not on Port C at ATMega103
; ATMega103 Port C have only output, so here no configuration is necessary
* in _temp1 , CF_ADDR_DDR
ori _temp1, &B00000111
* Out CF_Addr_DDR , _temp1
; waitms 1
*BASIC:WAITMS 1
; ldi r24, 1
; clr r25
; call _Waitms ; 1 ms delay
rjmp _DriveReset
[End]



[_DriveReset]
;------------------------------------------------------------------------------
; force CF-Card to a Hardware-reset
_DriveReset:
* sbi CF_Control_Out , CF_Reset
; waitms 1
ldi r24, 1
clr r25
call _waitms ; 1 ms delay
* cbi CF_Control_Out , CF_Reset
; waitms 500
clr r24
ldi r25, 2
call _waitms ; 512 ms delay
clr r25 ; set default no error
clc
ret
[End]



[_DriveCheck]
;------------------------------------------------------------------------------
; Checks, whether Card is plugged in: Pin CD1 is LOW
; if OK r24 = 1; otherwise 0
_DriveCheck:
clr r25
clc
* sbis CF_Control_In , CF_CD1 ; flashcard plugged in
ret
* ldi r25 , cpErrDriveNotPresent
sec
ret
[END]

recycle
18.11.2005, 22:22
@Marco78


Es gibt halt (noch) kein Programm, was das kann. Weil es kein Bedarf dafür gibt.

Naja, dass es keinen Bedarf für Decompiler gibt würde ich nicht behaupten.
Ich denke schon, dass eine ganze Menge Leute und Firmen für einen Decompiler der ihnen aus jedem beliebigen Programm die Quelltexte rekonstruiert ein paar Euro springen lassen würden ;-)

In Java ist das z.B. auch problemlos möglich. Bei einem guten Decompiler sieht der decompilierte Quelltext mitunter besser aus als das Original.
Dass es in Java so gut geht, liegt aber wohl daran, dass Java nur Bytecode und keinen Maschinencode generiert.

Ansonsten hast du natürlich recht. So einfach wie man Texte vom englischen ins deutsche und wieder zurück übersetzen kann, wird das bei Quelltexten die man compilert micht gehen.


@super_castle

Auch der Bascom Compiler dürfte beim Compilieren einige Optimierungen vornehmen.
Es wäre jedenfalls nicht besonders geschickt, wenn Bascom den knapp bemessenen Speicher eines µC mit langen Variablen und Funktionsnamen usw. vollpumpt.
Bei einigen Bascom-Anweisungen, z.B CONST und ALIAS steht sogar drin, dass sie keinen Speicher belegen. (weil der Compiler an den esntprechenden Stellen einfach den Namen durch den Wert der Konstanten ersetzt.
Wenn im decompilierten Quelttext nur Variabelnnamen, Funktionsnamen, Konstanten usw. fehlen würden, wäre der Quelltext zwar noch brauchbarere aber nicht mehr besonders gut lesbar.

Der Hersteller von Bascom wird glaube ich genauso wie die meisten anderen Hersteller von Programmiersprachen gar kein grosses Interesse haben, dass man seine Sprache decompilieren kann.
Die meisten Kunden wären davon sicher wenig begeistert, denn dann könnten sie ihre Quelltexte ja auch gleich im Web veröffentlichen.

SprinterSB
19.11.2005, 00:02
Wenn du avr-gcc verwendet hast, kommst du evtl an die Quelle dran, wenn du ein asm mitgeneriert hast (*.s) oder ein Precompile (*.i). Dann siehst du evtl, aus welcher Quelle das asm erstellt wurde.
Evtl geht es auch, wenn du noch das elf (*.elf) oder die Objekte (*.o) hast und Debug-Info erzeugt hast (Option -g).

Eine erhellende C-Quelle aus asm oder hex zu generieren ist nicht möglich.
asm kennt keine Variablennaben, Dinge können wegoptimiert worden sein, Makros sind aufgelöse, Funktionen können geinlinet worden sein, Schleifen können aufgerollt worden sein, Konstanten gefaltet, toter Code wurde eliminiert, Blöcke umsortiert ... und noch 1000 andere Dinge können passiert sein, bevor du dein hex aus ner Quelle bekommst.

PicNick
19.11.2005, 09:21
SprinterSB, ganz so schlimm ist es auch nicht. Ich hab mich einigermassen mit dem reverse-engineering beschäftigt, die BasCom- Source läßt sich aus der Assembler-Source recht gut erkennen, da BasCOm ja immer die gleichen Muster liefert. Aber insofern hast du recht, es bleibt eine Schweinearbeit und Precompiler-Sachen (z.B Const /Alias) lassen sich natürlich nicht rekonstruieren.

Hellmut
19.11.2005, 09:41
Nur so als Kommentar am Rande. Es macht als Programmierer von Kode für uC eine Menge Sinn sich vertraut zu machen wie der vom eingesetzten Compiler erzeugte Kode aussieht. Immer dann wenn Teile des Kodes zeitkritisch oder platzkritisch sind erwege ich den Nutzen diese Teile durch Assembler Kode zu ersetzen. Im Unterschied zur Programmierung für z.B. PC Programme, hat man im uC knappen Speicher und beschäftigt sich mehr mit Echtzeitproblemen.

SprinterSB
19.11.2005, 12:05
Gegen das eigentliche Problem, daß Daten verloren gehen -- wodurch auch immer -- hilft nur, die irgendwo zu sichern.
-- aus Ausdruck
-- auf ner CD
-- auf einem andern Rechner, zB ftp-Server im iNet. Die gibt's für lau (funpic.de, freenet.de...) und wenn man nur die Quellen sichert und nicht die ganzen binarys, geht das fix und braucht kaum Platz.

recycle
19.11.2005, 12:40
Gegen das eigentliche Problem, daß Daten verloren gehen -- wodurch auch immer -- hilft nur, die irgendwo zu sichern.
-- aus Ausdruck
-- auf ner CD
-- auf einem andern Rechner, zB ftp-Server im iNet. Die gibt's für lau (funpic.de, freenet.de...) und wenn man nur die Quellen sichert und nicht die ganzen binarys, geht das fix und braucht kaum Platz.

Glaubst du wirklich, dass es heutzutage noch jemanden gibt, der nicht weiss, dass man seine wichtigen Daten regelmässig sichern sollte?
Ich glaube das weiss heutzutage wirklich fast jeder und wenn die Daten futsch sind und man sie nicht vorher gesichert hat, ist das der allerletze Tipp den man bekommen möchte ;-)

Marco78
19.11.2005, 12:51
Und die Frage war ja auch nur wie man aus der Hex die man aus dem AVR ziehen kann den Bascom-Code herstellen kann.
Nicht wie es bei C geht, nicht wie man Assembler lernt, nicht was man machen kann, wenn ein paar Dateien fehlen und auch nicht, wie man Daten sichert.

Vitis
19.11.2005, 14:00
Was mich stutzig macht ist die Aussage "Quelldateien unwiderbringlich futsch".
Sowas gibts aber fast nicht. Haste die Platte noch? und wenn möglich noch nicht wieder beschrieben?
Da gäbs nämlich Progrämmchen die sowas noch auslesen können wenn z.B. die FAT den Bachrunter ist oder die partitionierung futsch etc.. Das wär glaub ich ein lohnenderer Ansatz als Reverse Engineering

m_herr
19.11.2005, 14:15
glaubt hier jemand im ernst an die story vom gelöschten code?
wenn ja, der soll sich bei mir melden, kann von mir günstig das brandenburger tor und den reichstag abkaufen

Memby
23.11.2005, 07:04
Hallo m_herr

Die Story stimmt leider mit dem gelöschten Code.
Ich habe auch eine Datensicherung vorgenommen, doch diese ist nicht mehr auf den neusten Stand, da ich seit der letzten Sicherung einiges dazu geschrieben habe.

Ich bin noch neu im µC Programmierung und habe viel Zeit und mühe in dieses Programm investiert. Manch einer würde das in ein, zwei Stunden oder einen Tag schreiben. Daher ist es ärgerlich, dass der neue Code weg ist. Der Code lag auf der Partition, auf der ich Linux installiert habe.
Wollte Linux auf eine andere Partition installieren, doch habe ich da einen Fehler gemacht, nicht genau geschaut und schon war’s passiert.
Es ist nicht nur dieser Code futsch, sondern alles was ich in Zusammenhang im µC gesammelt und erarbeitet habe.

Auf jeden Fall wird "Mann" aus Fehlern schlau.

Danke an allen die sich die Mühe machen und versuchen solchen Leuten wie mich zu Helfen. Ich habe auch wieder mal festgestellt, dass viele von euch wirklich versuchen zu Helfen und nicht einfach nur belangloses oder Unterstellungen posten.

Marco78
23.11.2005, 18:52
Ein Unglück kommt selten allein :(

Zieh dir doch am besten nochmal den Code aus dem AVR. Zum einen hast du ihn noch falls der AVR seinen Dienst verweigert, zum zweiten kannst du das Programm so zur Not noch öfters auf andere AVRs flashen. Und zu guter Letzt überwindest du dich vielleicht ja von heute auf morgen Assembler zu lernen.

Den ASM-Code kannst du dir mit AVR-Studio von Atmel anschauen wenn du die HEX (das Programm aus dem AVR) hast.