Du skal ind og kunne konfigurere memory osv. under startup, samt lave noget boot-session... Det kan sikkert (ikke??) lade sig gøre - men for fanden hvor ville jeg nødigt lægge mig ud med det...
Det kan du godt, du må bare ikke benytte andre funtioner end dem du har til rådighed i den bios, også de delphi funktioner der ikke benytter WinAPI\'et. Du kan lave det samme i delphi som du kan i C/C++, men C\'s klasse bib. er nok større og ikke så afhængig af api\'et, ( der er jo nogen der elsker at opfinde den dybe talerken igen ( C-folket ))
Lavede for mange år siden en boot-rekord til disketter så den kune boote fra hd, selv om der sad en disk i a, det som alle bios\'er har indbygget nu om stunder, det lavede jeg i TP55, og lidt asm.
JB >> jeg er sku ikke sikker på jeg har det mere, det var tilbage i 89-90, så det er lige et par år siden, men hvis jeg falder over det, skal jeg prøve at huske på det.
OK - spørger lidt dumt men hvad er principperne for en boot-record?
Hvis man godt kunne tænke sig at prøve delphi i DOS - hvordan gør man så? Bare et lille nemt/sjovt eksempelt ville være glimragende (gerne med lidt grafik)...
Kan man bruge OpenGL i Dos-Applications ligesom med Windows?
Et lille bonus-spørgsmål... :-)) MartinLind taler om ASM - jeg har set det blive omtalt nogle sjældne gange her på eksperten - Hvad er det for et sprog? og i hvilke situationer er det nødvendigt (hvis det er nødvendigt)? og hvad fordele/ulemper ved ASM?
ASM er en forkortelse for Assembler, hvilket er meget nært beslægtet med maskinkode eller om du vil: det \"rene sprog\" en CPU kører. ASM kode oversættes til maskinkode med et Assembler program. Med en DisAssembler kan man gå den anden vej, således at man laver en, fx., EXE-fil om til en række Assembler instruktioner - dette kan iøvrigt gøres selvom programmet oprindeligt blev skrevet i fx. Delphi.
Uanset CPU type, så består alle assembler sprog af en større eller mindre mængde forskellige kommando ord (instruktioner), der typisk dækker over ret simple operationer, fx. \"flyt indhold af register x til memory addresse yyy\" eller \"Hvis forrige instruktion gav negativt resultat, så hop til adresse zzz og fortsæt eksekvering fra denne adresse\". Som det ses er instruktionerne relativt simple - specielt set i forhold til en enkelt delphi instruktions linie, der typisk udløser tusinder af ASM instruktioner.
ASM/Assembler er ikke noget specifikt sprog, idet hver enkelt CPU har sin egen variant af ASM - Således er der forskel på instruktionssættene selv inenfor de enkelte CPU typer der benyttes i PC-kompatible computere, også selvom CPU\'erne er fra samme firma. En Intel Pentium har således flere instruktioner end en Inteh 80486. Det er dog sådan, at alle PC-compatible processore bygger på et fælles sub-sæt af instruktioner, hvorved de er kompatible nok til fx. at kunne køre samme operativsystem og programmer - det er ligesom det, der ligger i ordet kompatibel.
Fordelene ved Assembler: - Hurtigere eksekvering og mindre memory forbrug: Højniveau sprog som Delphi - og for den sags skyld C/C++ - gør brug af standard biblioteker, har indbygget range checks, tager mange parameter typer etc. Selv om nogle af disse ting typisk kan optimeres, med hensyn til hastighed og memory forbrug, så KAN de være langsommere end rutiner i Assembler. Jeg skriver KAN: Jeg har prøvet at lave nogle snævre løkker i Delphi og så set på maskinkode (assempler) outputtet fra compileren - og måttet indrømme at det faktisk var smartere lavet end den test assembler procedure jeg havde lavet ;) Det er vel i sidste ende et spørgsmål ASM programørens dygtiighed og rutine. - Et program skrevet i en hver form for højniveausprog vil slæbe en releativt stor runtime pakke med i EXE-filen (eller som selvstændige DLL\'er). Run-Time pakken indeholder en masse tin som måske eller måske ikke bliver brugt i det aktuelle progra, fx. at kunne læse og skrive data til/fra en disk fil. Hvis dette ikkke benyttes i programmet er det overflødigt. Et program skrevet i ASM kode vil typisk ikke indeholde mere end det som er skrevet i programmet. - Nogle ting kan simpelt hen kun lade sig gøre i Assembler, typisk meget maskinnære ting, dvs. device drivere til styring af visse hardware kredsløb, eller OS-nære rutiner så som visse service rutiner. - Portabilitet: Det er nemt at oversætte ASM koden fra en type CPU til en anden, selv CPU typer der er fjernt beslægtede.
Ulemper: - Der skal som sagt MANGE instruktioner til selv simple ting. Har man fx. en 8 bits CPU og man ønsker at kunne gange to 32 bits værdier, oplever man hurtigt at skaulle lave en function på 50-100 linier. - ASM programering kan være uoverskueligt - på det punkt minder det om BASIC - med masser af Jumps og Calls (GOTO\'s og GOSUB\'s) til forskelllige labels. Helt vildt bliver det hvis man arbejder med et disassemblet program, idet alle labels her er erstattet med kryptiske, forløbende numre, fx. L0001: i stedet for: SendRS232Char: - Man skal tænke på alting selv, fx. range checks etc., som højniveau compilere normalt klarer for dig.
Der er sikkert mange flere ulemper/fordele - spring ind hvis i har et bidrag....
Mht. Delphi ASM genereing, skal du nok stå tidligt op, hvis du skal hamle op med den.
Mht. til Delphi og Dos, tror jeg nok du skal helt tilbage til Delphi1 for at få en IDE du kan bruge til DOS, men hvis du vil skrive kode til dos, bruger du også et OS ( DOS = Disk Operativ System ), så hvis det var et OS du ville lave, skal du IKKE benytte dig af anden hjælp en den du kan få fra BIOS ( Basic Input Output System ), som er den rom du har sidende i din maskine, og som du kommer ind i når du går ind i din masikine setup.
delphi>> 1000 tak for din meget beskivende forklaring af asm. - Hvis du ligger inde med et lille eksempel med asm, kunne det være sjovt at se nærmere på det (gerne et der kan sammenlignes med et Delphi eksempel - det behøver absolut IKKE at være ret langt)
Det er nu ikke meningen at jeg vil lave et OS i Delphi!!! Men jeg synes bare at det ville være en interresant tanke at vide om det kan lade sig gøre med Delphi...og det lader hvist til at folk mener at det kan det...
procedure TForm1.Button1Click(Sender: TObject); Var x : integer; y : Integer; Z : Integer; begin x := 1; y := 2; z := x + y; ShowMessage(\'Z = \' + IntToStr(Z)); end;
Der udfører hvad der svarer til de fire linier mellem Begin og End. Resten er noget mere eller minder (mest mindre) overfødigt fyld, så som at sætte stacken op til de benyttede parametre (bl.a. den skjulte \"Self\" værdi) og variable (x, y og z).
Hvad du ikke ser, er at der andre steder i dit program ligger nogle data, bl.a. til texten \'Z = \'.
Hvad der bør være åbenlyst er, at ASM kode fylder mere og består af mere \'primitive\' instruktioner end for et højniveau sprog - og så er de benyttede Intel 80x86 instruktioner endda temmeligt complexe i forhold til så andre processor typer, dvs. RISK CPU\'er.
Lad mig forklare .. Pascal koden springer vi over ...
Function GetCheckSum (const FileName : TFileName) : Integer; var F : File of Integer; Fsize : Integer; Buffer : Array [0..500] of Integer; begin FileMode := 0; AssignFile ( F , FileName); Reset ( F ); Seek ( F , FileSize ( F ) div 2); Fsize := FileSize( F )-1-FilePos( F ); if Fsize > 500 then Fsize := 500; BlockRead ( F, Buffer, Fsize); CloseFile ( F ); asm xor eax, eax //NULSTILL eax det skal bruges til at tælle sammen i xor ecx, ecx //NULSTILL ecx det skal bruges til at holde vores tælle variabel lea edx , Buffer //Put adressen på Buffer over i edx registeret. @again: //En label vi kan hoppe til PRÆCIS magen til en label i pascal (Ikke at forveksle med TLabel) add eax, [edx + 4*ecx] //En integer fylder 4 BYTE (32 bit) så hvis vi skal have fat i Et eller andet element i vores //Buffer array ligger det på adressen Starten af array + (4*Nummeret på elementet) //Adressen på starten af arrayet ligger i edx registeret. Vores tæller variabel er ecx så //regnestykket hedder edx + 4*ecx. Da vi ikke skal have adressen men der der ligger på adressen //stopper vi det hele ind i []. Det hele bliver stoppet over i eax. inc ecx //tæl ecx op med 1 (inc er en forkortelse af increase) cmp ecx, fsize //sammenlign (cmp er en forkortelse af compare) jl @again //hvis ecx < fsize så goto again lablen vi satte før (jl er en forkortelse af Jump less) mov @result, eax //kom resultater af vores tællen sammen over i result end; end;
Fidusen ved at tælle sammen på denne måde er at hvis tallet vi ligger sammen bliver forstor til at være i en integer ja så øber tælleværket bare over.
zerohero>> Du spurgte efter hvornår man kan/skal anvende Assembler ...
Du skal anvende Assebmler til ting der ikke er implemteret på forhånd, fx hvis du vil måle CPU Speed, eller få PC Speakeren til at sige lyde :
Her har du et eksemple til måling af CPU Speed :
Function GetCpuSpeed : Real; Function IsCPUID_Available : Boolean;assembler;register; asm PUSHFD {direct access to flags no possible, only via stack} POP EAX {flags to EAX} MOV EDX,EAX {save current flags} XOR EAX,$200000 {not ID bit} PUSH EAX {onto stack} POPFD {from stack to flags, with not ID bit} PUSHFD {back to stack} POP EAX {get back to EAX} XOR EAX,EDX {check if ID bit affected} JZ @exit {no, CPUID not availavle} MOV AL,True {Result=True} @exit: end;
const Delay = 500;
var TimerHi, TimerLo: Integer; PriorityClass, Priority: Integer; begin Result:=0; if not IsCPUID_Available then Exit; PriorityClass := GetPriorityClass(GetCurrentProcess); Priority := GetThreadPriority(GetCurrentThread);
asm db $0F db $31 { $0F31 op-code for RDTSC pentiun instruction returns a 64 Bit Integer} mov TimerLo, eax mov TimerHi, edx end;
SleepEx(Delay , FALSE);
asm db $0F db $31 { $0F31 op-code for RDTSC pentiun instruction returns a 64 Bit Integer} sub eax, TimerLo sbb edx, TimerHi mov TimerLo, eax mov TimerHi, edx end;
BorrisHolt>> Hvordan fanden ved du alt det!!! (måløs :-)) Jeg mener det er da komplet umuligt at vide de forskellige koder til assembler. Er det bare noget du ved????
Der er nu ikke så utrolig svært at kunne ASM, idet sproget(ne) er meget logisk opbygget. Der er således tale om, at alle instruktioner kan opdeles i en håndfuld kategorier eller to. Fx. sidder jeg lige nu og laver et assembler program til en Atmel processor. Med hensyn til antallet af instruktioner, er det en rimelig simpel processor - det fede ved den er at den har indbygget RAM, Flashrom, I/O porte, RS-232 osv. osv. Dvs. et helt computer system er stort set indbygget i en enkelt kreds, hvilket passer fint til den aktuelle opgave, hvor jeg skal styre et kamera, via RS-232 (VISCA), fra nogle potentiometre og switche. Printet kræver tre kredse: en CPU, en A/D-converter, som kunne være indbygget i CPU\'en hvis jeg havde valgt en anden model i serien - men den har jeg ikke på lageret) samt en strømforsynings dims.... CPU\'ens instruktions sæt er opdelt i 4 grupper: I parentes er de oftest anvendte talt med i hver kategori (dækker 99% af alle opgaver).
Aretmetic and Logical instructions: (28) Instruktioner til matematiske operationer, så som... - Additioner: ADD, ADC, ADI. Bemærk de starter med AD - Subtraction: SUB, SUC, SUBI. Starter alle med SU eller SB. - Multiplication: MUL, MULS, FMUL. Tydeligt, ik\'?
eller logiske instruktioner så som: - Logisk AND: AND, ANDI - Logisk OR: OR, ORI - Set/Clear: SER (Set register), CLR (Clear Register)
Branch Instruction: (38 - Atmel CPU\'er er stærke mht. Brach) Instruktioner der hopper til andre steder i programmet, oftest afhængigt af status af et eller flere flag. - RJMP: Jump (Goto) - RCALL, CALL, ICALL: Forskelige udgaver af Call (GoSub) - RET, RETI: Return fra subroutine eller Interrupt routine. - CP, CPI: Compare instruktioner, der som resultat sætter status flag. - BRCC, BRCS: Branch if carray clear (-set). Hop hvis carry flag... - BREQ: Branch if equal flag set (depends on previous (compare) operation) - BRNE: Branch if not equal flag set (-- do --)
Data transfer Instructions: (39) Instruktioner der flytter data, dvs. en 8 eller 16 bits værdi, fra et register, memory adresse,I/O port eller direkte værdi til et register, memory adresse eller I/O port. - MOV: Move. Kopier indhold af et register til et andet. - LD : Load. Læs indhold af memory adresse ind i et register. - ST : Store. Det modsatte af Load. - IN, OUT: Flyt indhold til/fra register fra/til I/O port.
Bit and Bit-test instructions: (31) Instruktioner som arbejder med eller sammenligner enkelte bits i et register. I denne gruppe findes, sjovt nok, også instruktioner til Rotate og shift af hele registre (burde efter min mening høre til de logiske operationer, som fx. AND, OR eller CLR). - ROR: Rotate bits i register Right, Bit 7 = carry, Carry = Bit 0 - LSR: Logic shift right, Bit 7 = 0, Carry = bit 0. (= x/2!) - ROL: Rotate bits i register left, Bit 0 = carry, Carry = Bit 7 - LSL: Logic shift left, Bit 0 = 0, Carry = bit 7. (= x*2!) - SEN, CLN: Set eller Clear Negativ status flag. - SEC, CLC: Set eller Clear carry flag. - SBI, CBI: set eller Clear enkelt bit i et register.
Som det fremgår af ovenstående, så er ASM sproget i sig selv egentligt blot et spørgsmål om at sætte sig ind i ~100 instruktioner (antal afhænget se\'følig af CPU typen), hvoraf langt de fleste er på 3 bogstaver og er opdelt i meget enslydende betegnelser, således at de er rimeligt nemme at huske. Fx. er det nemt at huske at BREQ står for BRanch if EQual.
Langt mere problematisk er det at hitte ud af de rigtige programerings modes. Dette er fordi at den \"samme\" instruktion kan forståe på flere måder, typisk op til 5-7 stykker, afhængigt af hvilke registre der er benyttet og hvorledes de er beskrevet. Dette er som regel et problem i forbindelse med instruktioner der involverer memory adresser, for eksempel:
LD R10, R27 ; Load indholdet af den memory adresse, der er indeholdt ; i register 27, ind i register nr. 10.
LD R10, R27+ ; Load indholder af den memory adresse, der er indeholdt ; i register 27, ind i register nr. 10. Forøg derefter ; indholdet af reister 27 med 1.
LD R10, [R27] ; Load indholdet af den memory adresse, der er indeholdt ; i den memory adresse, som er indeholdt i register 27, ; ind i register 10. (= et tabel opslag).
Dette var tre forskelige modes, Direct, Direct with post-increment og Indirect. I alle tilfælde er det en Load instruktion.
Håber ikke det forvirrer for meget, men nu vil jeg sq hjem....
Delphis inline assembler understøtter, så vidt jeg ved, det fulde ASM sæt fra Intels CPU\'er. Selv hvis dette skulle vise sig ikke at være tilfældet, så kan man bruge de \"gamle\" Turbo Pascal inline commandos, hvor man indsætter de rå hex-/maskinecodes.... Den virker ALTID!
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.