Autor Beitrag
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 06.10.07 10:40 
Hi
ich brauche in ASM eine Zufallszahl, die zwischen 2 werten liegt
GettickCount liefert mir 1) 4 Bytes 2) Weis ich nicht wie ich die in einen Bereich bringe

Es soll komplett ASM sein und darf nur max 2 Register verwenden (also EAX+noch eins)
wenns nicht mit 2n geht dann mit sowenig wie möglich
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1653
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Sa 06.10.07 11:11 
Hallo,

schreibe es in Delphi und schau was der Compiler daraus macht.
Mit F5 Breakpoint setzen und in CPU-Ansicht wechseln.
Also melde Dich mit deinem Entwurf zurück

Gruß Horst
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 11:13 
Genial ;-) Endlich mal wieder ne Herausforderung ;-)

Darf Stack genutzt werden? Stehen Variablen zur Verfügung (zur freien Verfügung)?

Allerdings ein wenig vorab: Allein mit GetWindowLong wird das nicht viel werden ...

Ich probier mal was mit State (4 Byte Global), unter Nutzung von EAX und EDX.

@Horst_H: Der Delphi-Compiler ist bei sowas zu ineffizient, da man ihm die Einschränkung der Register-Anzahl nicht beibringen kann.

Edit: Hab mal kurz was geschrieben ... Ist ungetestet (und auch noch nicht gedebuggt), sollte aber laufen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
var
    Seed: DWORD;

procedure TForm1.Button1Click(Sender: TObject);

    function GetRandomBetween(L, H: DWORD): DWORD;
    asm
        //  EAX ==> Low bound
        //  EDX ==> High bound (exclusive)
        //  EAX <== Random result within EAX <= Result < EDX

        SUB     EDX, EAX    //Check for EDX > EAX
        JNA     @@Finish    //If not, always return EAX

        PUSH    EAX
        PUSH    EDX

        XOR     EDX, EDX
        INC     EDX         //End Marker

    @@GetBitLoop:
        MOV     EAX, DWORD PTR [Seed]
        ADD     EAX, EAX
        ADC     EDX, EDX

        PUSHF               //Store the overflow flag of this operation

        PUSH    EDX         //Init the Feedback
        AND     EDX, 1
        
        PUSH    EAX         //Store the Seed
        AND     EAX, $DEADBEAF  //Rückkoppelfunktion; FEEDBACC, CAFECAFE, FADEDEAD and others possible ;-)

    @@GetFeedbackLoop:      //XOR all non-zero bytes of the feedback ...
        ADD     EAX, EAX
        ADC     EDX, 0
        TEST    EAX, EAX
        JNZ     @@GetFeedbackLoop
        
        POP     EAX             //Get the new seed value
        AND     EDX, 1
        ADD     EAX, EDX        
        MOV     DWORD PTR [Seed], EAX

        POP     EDX
        POPF
        JNO     @@GetBitLoop
        
        MOV     EAX, EDX
        XOR     EDX, EDX
        DIV     DWORD PTR [ESP]

        POP     EAX
        POP     EAX

        ADD     EAX, EDX
    @@Finish:
    end;

begin
    Caption := IntToStr(GetRandomBetween(10,20));
end;


Als Initialisierung empfiehlt sich RDTSC, da dieser ausreichend unvorhersagbar ist (auf den meisten Systemen). GetTickCount funzt aber auch.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 06.10.07 12:50 
hmmm.gehts nicht einfacher?
die grenzen können dierekt im code stehen

und kannst du kommentare dran amchen? wills ja auch verstehen
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 12:52 
Der Source ist doch kommentiert :nixweiss:

Einfacher sähe die Routine aus, wenn man mehr Register zur Verfügung hätte ;-)

Ansonsten: Ich hab in der Routine einfach ein simples Suche in Wikipedia LFSR umgesetzt ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 06.10.07 15:30 
ja aber es geht noch einfacher wenn der seed nicht außerhalb initalisiert werden muss und die grenzen fest sind (konstanten)

kannst du das entsprechend umschreiben?
PS: wegen den push und pop: wird der stack am ende anders sein? das wäre nämlich noch ein problem
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 15:37 
Naja, alles unterhalb der Rücksprungadresse (in meiner Version, wenn ich korrekt gerechnet hab 20 Bytes) wäre "undefiniert".

Mit Konstanten müsste es IMHO so aussehen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
var
    Seed: DWORD;

procedure TForm1.Button1Click(Sender: TObject);

    function GetRandomBetween: DWORD;
    const
        LowBound = 10;
        RangeSize = 10;
    asm
        //  EAX <== Random result within EAX <= Result < EDX

        XOR     EDX, EDX
        INC     EDX         //End Marker
    @@GetBitLoop:
        MOV     EAX, DWORD PTR [Seed]
        ADD     EAX, EAX
        ADC     EDX, EDX

        PUSHF               //Store the overflow flag of this operation
        PUSH    EDX         //Init the Feedback
        AND     EDX, 1
        
        PUSH    EAX         //Store the Seed
        AND     EAX, $DEADBEAF  //Rückkoppelfunktion; FEEDBACC, CAFECAFE, FADEDEAD and others possible ;-)
    @@GetFeedbackLoop:      //XOR all non-zero bytes of the feedback ...
        ADD     EAX, EAX
        ADC     EDX, 0
        TEST    EAX, EAX
        JNZ     @@GetFeedbackLoop
        
        POP     EAX             //Get the new seed value
        AND     EDX, 1
        ADD     EAX, EDX        
        MOV     DWORD PTR [Seed], EAX

        POP     EDX
        POPF
        JNO     @@GetBitLoop
        
        PUSH    RangeSize
        MOV     EAX, EDX
        XOR     EDX, EDX
        DIV     DWORD PTR [ESP]
        POP     RangeSize

        MOV     EAX, EDX
        ADD     EAX, LowBound
    @@Finish:
    end;

begin
    Caption := IntToStr(GetRandomBetween);
end;


Brauch aber immer noch 12 Byte zzgl. Rücksprung-Adresse.

Wozu brauchst Du den Stack unverändert? Kannst Du bitte dein genaues Ziel etwas genauer darstellen?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Sa 06.10.07 15:39 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function randomrange(a,b: integer): integer;
asm
  push eax
  xchg eax, edx
  sub eax, edx
  imul edx, [randseed], $08088405
  inc edx
  mov [randseed], edx
  mul edx
  pop eax
  add eax, edx
end;


benutzt die originale random funktion von delphi

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Sa 06.10.07 15:43 
wenns fest sein soll:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
function randomrange(a,b: integer): integer;
asm
  mov eax, 100 // zahlen von 0-99 (obere grenze-untere grenze)
  imul edx, [randseed], $08088405
  inc edx
  mov [randseed], edx
  mul edx
  mov eax, edx
  add eax, 20 // untere grenze
end;


satck wird nicht verändert

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 06.10.07 15:49 
ok...ich möchte in einem asm teil einen string auf einen zufallsbuchstaben verändern
brauche also keine prozedur sondern ein stück code, oder etwas was ich per call aufrufen kann
ohne das der stack oder mehr als das eine register verändert wird

die obere/untere grenze soll sein, damit es immer der ascii wert eines buchstabens/zahl wird

könntest du also das mit dem seed dann auch mit ersetzen? (durch gettickcount, oder so)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 16:15 
Dir ist die Verwendung von PUSH und POP aber schon vertraut?

Kannst Du mal deinen derzeitigen Source zeigen?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Sa 06.10.07 16:29 
Hast du überhaupt einen Plan von asm? Erst was haben wollen, dann bekommste es und kannst es noch nicht mal selbst umschreiben.

Bau halt das nach:

form1.caption := char((GetTickCount mod 26)+ord('a'));

sind 3 assembler Befehle


Edit:
ich hab mir deine letzten Topics alle mal anegschaut, ohne dass du sagst was du vor hast werd ich nicht mehr helfen.

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 06.10.07 18:42 
ja sry...ich bin ne so gut in asm
ich kenne die meisten standartbefehle und habe schon simple sachen geschrieben
aber was z.b. ist imul/mul?

aber dein letzter tip ist genau das was ich gesucht habe...so werd ichs hinkriegen
@uall:warum willst du mir nicht mehr helfen?
@benbe: ja ist. push und pop is klar...mein prob war ja das der stack nicht verändert werden darf und ich konnte die aufrufe von push und pop nicht ganz nachvollziehn...
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 19:03 
Für mich gilt aber auch das Gleiche wie bei uall auch: Ohne dass Du uns erklärst, was Du vor hast, und wie dein jetziger Source aussieht, werd ich nicht weiter helfen, da das in jedem Fall ne Zeitverschwendung wird.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.