Gå til innhold

Anbefalte innlegg

Har i det siste blitt ganske så interessert i compilers, og da ikke interpreted compilers, men binary compilers.

Det jeg har funnet ut er at en compiler går gjennom tre "stages", bl.a. sjekking om syntax errors, og omgjøring til assembly-kode.

 

Dette er forsåvidt greit, men jeg sitter igjen med det største spørsmålet. Når compileren gjør om assembly-kode om til binary, hvordan vil da sluttresultatet fungere? Når compileren gjør om high-level kode til low-level kode (asm), og deretter til binary, hvordan fungerer slike ting som "if", "else", functions og procedures? I prosessoren så er jo alt 0 og 1, true or false (right?). Men jeg forstår fortsatt ikke hvordan det hele henger sammen når det har blitt konvertert til binary.

 

Dette er ganske vanskelig å forklare, men jeg forsøker så godt jeg kan. Kort oppsummert, så lurer jeg ganske mye på hvordan en slik .exe er bygget opp, og hvordan alt henger sammen. Muligens litt vanskelig å svare på, men jeg hadde satt stor pris på alle svar jeg evt. vil få.

Lenke til kommentar
Videoannonse
Annonse

Husk at prosessoren leser maskinkode ikke assembly.

 

Assembly er jo egentlig bare oversatt til noe forståelig for oss vanlige dødelige.

 

Dette er det som prosessoren leser:

 

804dbd7b 8bff

804dbd7d 55

804dbd7e 8bec

804dbd80 83ec10

804dbd83 53

804dbd84 56

804dbd85 8bf1

804dbd87 837e0400

804dbd8b 8d4df0

804dbd8e 8d5e08

804dbd91 8b03

804dbd93 8955f8

804dbd96 894df4

804dbd99 894df0

804dbd9c 7e5f

 

I hex da, prosessoren leser det selvsagt som binært.

(Forenklet sett da, det er egentlig enda litt mere avansert måten prosessoren tolker instruksjoner)

Endret av fenderebest
Lenke til kommentar
  • 3 uker senere...
Gjest Slettet+9871234

Dette er riktig:

 

Husk at prosessoren leser maskinkode ikke assembly.

 

Assembly er jo egentlig bare oversatt til noe forståelig for oss vanlige dødelige.

 

Dette er det som prosessoren leser:

 

804dbd7b 8bff

 

......................

 

I hex da, prosessoren leser det selvsagt som binært.

(Forenklet sett da, det er egentlig enda litt mere avansert måten prosessoren tolker instruksjoner)

 

Har i det siste blitt ganske så interessert i compilers, og da ikke interpreted compilers, men binary compilers.

Interpreted compilers er etter min mening misvisende. Interpreter / tolker er vel det rigtige, da koden nettopp ikke kompileres til maskin kode. PHP / Zend engine er en slik tolker. I Simula bruker du en com commando når du kompilerer kildekoden til maskinkode.

 

 

Det jeg har funnet ut er at en compiler går gjennom tre "stages", bl.a. sjekking om syntax errors, og omgjøring til assembly-kode.

Det kan vel variere fra kompilator til kompilator. Min erfaring med Borlands C++ kompilator, nå C++ Builder 2009 Professional overtatt av Embarcadero er:

  1. Kompilering (Sjekking av syntax)
  2. Lenking av object filer (interne og eksterne). Her kan du få lenke feil.
  3. Maskin kode (exe) file som legges i en systemtabell i minnet når programmet kjores.

Dette er forsåvidt greit, men jeg sitter igjen med det største spørsmålet. Når compileren gjør om assembly-kode om til binary, hvordan vil da sluttresultatet fungere? Når compileren gjør om high-level kode til low-level kode (asm), og deretter til binary, hvordan fungerer slike ting som "if", "else", functions og procedures? I prosessoren så er jo alt 0 og 1, true or false (right?). Men jeg forstår fortsatt ikke hvordan det hele henger sammen når det har blitt konvertert til binary.

 

Din hjerne fungerer på en måte. En datamaskins "hjerne" fungerer på en annen måte. Datamaskinen leser bit strømmer. Jeg var så vidt innom et kurs på Mat Nat på UIO i C* algebra, mer presist bit stream algebraen, hvor foreleser var sønn av tidligere statsminister Trygve Bratteli, Ola Bratteli

 

For de som graver dypere, Google:

 

Ola Bratteli bit stream algebra

 

Ola Bratteli bitstream algebra

 

Ola Bratteli C* algebra

Endret av Slettet+9871234
Lenke til kommentar

Her er en episode av Software-Engineering Radio (se-radio.net) som handler om hvordan GCC fungerer:

 

http://www.se-radio.net/podcast/2007-07/ep...1-internals-gcc

 

Kanksje dette er en smule off-topic da podcasten ikke handler om å gjøre asm til bin direkte, men heller mer abstrakte løsninger;

 

* GCC består av en frontend som tar kildekode være det C, C++, Java eller noe annet og gjør det om til en felles representasjon som "middleend" delen kan gjøre optimaliseringer på. Denne representasjonen består bla.a. av et "parse-tree" som splitter opp utrykk som C=A+B opp i noder forbundet av operatorer (+-*/=).

 

* Middleend modulen tar koderepresentasjonen fra frontend og gjør den om til psudo-assembly eller "Register transfer language" (RTL).

 

* Backend tar den prosessor-nøytrale RTL-koden og gjør den om til ønsket assembly kode.

 

Hele veien gjøres det optimaliseringer om jeg ikke husker feil.

 

Intr. stoff :)

Tenker jeg skal lese litt mer om GCC på wikip;

http://en.wikipedia.org/wiki/GNU_Compiler_Collection

Lenke til kommentar
  • 2 uker senere...
  • 8 måneder senere...

Du skriver først assembler koden i form av mnemonics. Mnemonics ble opprettet for å gjøre det enklere å kode maskinspråk. Mnemonics betyr "å huske". Mnemonics er ord som erstatter oppkoder som prosessoren forstår.

 

Når du skriver assembler kode så skriver du mnemonic koder og de består som regel av ord 3-4-5-6 bokstaver langt slik som cmp, mov, movzx, jmp, call etc.

 

Hver mnemonic har sin representative oppkode tall som prosessoren forstår.

 

Hvis du snakker om if-then og slikt i høynivåspråk, så konverteres det til en lang rekke (noen ganger komplekse) sammensetninger av oppkoder for å få til den effekten ditt programmeringsspråk er ute etter. Det fins ingen fasit på hva som genereres, det avhenger av hvordan de som skrev kompilatoren tenkte.

 

Iallefall, prosessen det skjer er at du har en kildekode (som regel .asm filer som inneholder mnemonics). Siden din cpu ikke forstår mnemonics så må assembleren gjøre disse om til oppkoder. Oppkoder avhenger av hvilken cpu du skriver for og hvilken assembler du bruker. Så genererer assembleren objekt filer med binær kode.

 

For å få et dataprogram må du bruke en linker, linkeren "syr" sammen og henter ut nødvendig data fra biblioteker og syr det sammen til en kjørbar exe fil.

Lenke til kommentar
Gjest Slettet+9871234

Hva er forskjellen på å telle binært, oktalt, desimalt eller hexadesimalt? Jeg ser kun en forskjell, antall tastetrykk for å representere f.eks 100 binært og 100 hexadesimalt. Forskjellen på deg og en datamaskin er at datamaskinene er stein dum, men den er rask på noen operasjoner. Lær deg å opptre som et menneske, men tenke som et dataprogram / Bot. Eksempel. Når du ser en internettside, ser du design, farger etc. Dette er irrelevant / støy for en bot som indekserer innhold.

 

Dra til Mat Nat UIO og lær deg hva en isormorphi 1 - 1 relasjon er.

 

Da vil du (dere) forstå at dette er lett. It er elementeær matte.

 

Det som gjør It / programvare vanskelig er kompleksiteten, antall linjer i programmet. Ofte skyldes dette dårlig programmering.

 

Jfr. objekt overloading i PHP.

Endret av Slettet+9871234
Lenke til kommentar

En PE .EXE fil (Portable Executable) består av først et bittelite 16-bit DOS program som kun sier "This program cannot be run in DOS mode." eller lignende. Deretter følger en Header, etterfulgt av en OptionalHeader. Disse forteller litt om strukturen i .exe fila, for eksempel entrypoint, alignment, relocation table og alle de forskjellige seksjonene i .exe, og hvilket instruksjonssett programmet er laget for.

 

Programmet i seg selv, består av en rekke instruksjoner, som avhengig av instruksjonssett, er kodet opp av en relativt enkel struktur. Det er bare MIPS jeg har noe særlig god peiling på (har skrevet en assembler og virtuell maskin for MIPS) men har også sett på x86 som er betydelig mer komplisert enn MIPS.

Siden jeg kan MIPS vesentlig bedre, tar jeg det som eksempel:

 

En MIPS instruksjon kan være av fire forskjellige typer, R-Type, I-Type, J-TYPE og Co-Processor instruksjon.

En R-Type ser slik ut:

6 bit: Opcode

5 bit: rs register (source register)

5 bit: rt register (target register)

5 bit: rd register (destination register)

5 bit: shamt (Shift amount)

6 bit: funct

 

For eksempel

ADD $a0, $t0, $t1 // a0 = t0 + t1

 

Deretter har vi I-Type

6 bit : opcode

5 bit : rs

5 bit : rt

16 bit: immediate

For eksempel

ADDI $a0, $v0, 100 // a0 = v0 + 100

 

Og nest sist, J-Type:

6 bit : opcode

26 bit : relativ addresse

 

For eksempel:

j 4 // Hopper 4 instruksjoner fremover, altså programpekeren blir flyttet 4*4 bytes fremover.

 

Co-prosessor instruksjoner har jeg ikke vært borti :)

 

x86 er som sagt vesentlig mer komplisert enn MIPS.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...