Stack, little Endianness, byte-weiser Aufbau?

2 Antworten

0x1000 0x1001 0x1002 0x1003 0x1004 0x1005 0x1005 0x1007 0x1008
                                                          ESP
                            ESP <--------------------------+ 
                              0x15   0x08   0x00   0x00  ;1. push
ESP <------------------------+
  0x11  0x47   0x00   0x00                               ;2. psuh

Es werden 32-Bit Register gepusht, daher werden auch alle 32 Bit auf den Stack gepushst und der SP um 4 Adressen dekrementiert.

Ein push bei x86 besteht aus 2 Schritten:

  • Dekrementierung des SP um die Operandengröße
  • SS:ESP = Source-Reg.

RedDevil1982 
Beitragsersteller
 29.05.2023, 21:40

Warum wird bei dir in deiner Grafik zuerst die 00, dann nochmal 00

08 und dann die 15 gepuscht.

Wenn ich im Speicher die 0815h liegen habe, z. B. als little Endian

15 08 00 00 15 auf der kleinsten Adresse ... 00 auf der höchsten Adresse

Warum wird dann zuerst die 00 auf den Stack gepusht?

Müsste hier in meinem Fall nicht zuerst die 15 (da kleinste Adresse) gepusht werden bei little Endian?

RedDevil1982 
Beitragsersteller
 29.05.2023, 21:23

Ich gehe davon aus, das deine Darstellung der Stack ist. kann oben ist die höchste Adresse im Stack 0x1008 ganz unten die kleinse 0x1000

Es wird die erste hex Zahl 0815h gepuscht.

=> Warum füllst du hier die Zahl noch mit 0x00 zweimal auf?

Ich weiß es nicht deshalb meine Nachfrage => 4 Byte Zahl warscheinlich.

hex-Zahl 0815h in little Endian gespeichert:

15 08 00 00 kleinste Adresse die 15 .... höchste Adresse die 00 ganz rechts.

Warum pusht du auf den Stack zuerst die 00 ganz rechts?

KarlRanseierIII  29.05.2023, 21:59
@RedDevil1982

Habe ich fälschlicherweise zu schnell geschossen und als Big Endian abgelegt?

Mal sehen 0815h auf 32 Bit erweitern

00 00 08 15 h.

Bei einem 'Kleinender' fange ich am kleinen Ende also dem 'least significant byte' bei niedrigster Adresse an, demnach wäre das 15 08 00 00h.

Beim push wird das Wort dann auf den Stack gepusht, dabei ändert sich die Reihenfolge nicht:

push eax       ; pushing eax to stack equals:
SUB ESP,4      ; Decrement SP by 4 (32 Bits word)
MOV [ESP],EAX  ; Mov Reg Value to Mem-Location ESP is pointign to.
RedDevil1982 
Beitragsersteller
 29.05.2023, 22:30
@RedDevil1982

Noch ne abschließende Frage, wenn man einen Kleinender hat

15 08 00 00h und jetzt wird dieser auf den Stack gepusht

push eax ;

Wir dann die 15 zuerst, dann die 08, dann die 00 und 00 gepusht so das die einzelnen Bytes an unterschiedlichen Adressen im Stack liegen. So wäre ja zumindest nach der Grafik, wo du am Anfang gezeigt hast?

An der höchsten Adresse im Stack die 15 0x1008, dann die 08 an der 0x1007 usw.

?

KarlRanseierIII  29.05.2023, 22:52
@RedDevil1982

Die Sache ist die, der Push von eax pusht ein 32-Bit Maschinenwort und genau das passiert im Endeffekt auch, es ist ein 'Memwirte' mit 32 Bits an die Adresse von ESP.

Machen wir mal was anderes:

000002f0  b8 15 08 00 00 b8 03 00  00 00 bb 00 00 00 00 b9  |................|
00000300  00 00 00 00 ba 20 00 00  00 cd 80 b8 04 00 00 00  |..... ..........|

Ausschnitt eiens Hexdumps eines Objects, schauen wir genauer hin:

b8 15 08 00 00 b8 03 00  00 00 bb 00 00 00 00 
^ Opcode für MOV immediate to eax
   15 08 00 00 (0815h)
               ^ imm. to eax (3)
                               ^ immediate to ebx (0)

Zugehöriger Ausschnitt aus ASM-Datei:

        mov eax, 0815h
        mov eax, 3 
        mov ebx, 0

Warum steht im Object die 15 08 00 00? Weil der Assembler 'sieht', daß das Ziel ein 32-Bit Register ist und deswegen den Wert in Little Endian in 32 Bit im Executeable ablegt.

x86 hat little endianness... d. h. low-byte hat eine kleinere Adresse als die higher seienden bytes... das setzt sich auf dem Stack oft so fort... muss aber nicht so sein... die stack endianness kann anders sein... bei x86 ist es so, dass das highest-byte zuerst ge-push-t wird und zuletzt das am lowest seiende Byte...

eax und ebx haben je 32bit... also 4 Bytes... warum push-t du nur die Bytes, die nich Null sind? lol

müsste esp nicht wenigstens auf das freie Kästchen gleich unter 47h zeigen?

https://stackoverflow.com/questions/18470053/relation-between-endianness-and-stack-growth-direction

Woher ich das weiß:Studium / Ausbildung – Absolvent/Universität

RedDevil1982 
Beitragsersteller
 29.05.2023, 21:15

"eax und ebx haben je 32bit... also 4 Bytes... warum push-t du nur die Bytes, die nich Null sind? lol"

Ich habe doch eine hex Zahl 4711h Wie sieht dies Zahl als Byte Zahl aus?

Little Endian => 11 47 00 00

Big Endian => 47 11 00 00

Oder?

=> Warum schreibt man als Byte immer nur 2 Stellen des hexa. Also 47 oder 11

1 Byte = 8 Bit = 2^7 = 128

LUKEars  29.05.2023, 21:27
@RedDevil1982

also was EAX&EBX angeht: ja... genau... hast recht...

aber: 8 Bit sind 256 Möglichkeiten... also 2^8... also 0, 1, 2, 3, ...., 253, 254, 255

stimmt's?

was meinst du? im Hexadezimal-System kann man ein Byte immer mit höchstens zwei Stellen schreiben... jede Stelle hat 16 Möglichkeiten... 0,1,2,3,...,14,15

stimmt's?

RedDevil1982 
Beitragsersteller
 29.05.2023, 21:36
@LUKEars

2^8 = 256 passt.

Ich habe eine Zahl 4711h, eine Hexa, diese ist dezimal 18193 dafür braucht man 2^15 Bit ....

Wenn ich diese Zahl 4711h als little Endian darstelle

11 47 00 00 Warum füllt man diese Zahl noch rechts mit 00 00 auf?

Oder was soll dieses 00 00 bedeuten? Ich habe 4 Byte in meinem Register eax

Jede Zahl repräsentiert 1 Byte.

Little Endian kleinstes Byte an kleinster Adresse, deshalb 11 zuerst

Big Endian größtes Byte an kleinster Adresse, deshalb 47 zuerst.

Diese Auffüllungen mit den 00 00 ist nur weil mein Register eax 4 Byte breit ist, und außer dem 4711h nichts mehr drinnen steht, oder?

LUKEars  29.05.2023, 21:40
@RedDevil1982
11 47 00 00 Warum füllt man diese Zahl noch rechts mit 00 00 auf?

eigentlich füllst du die Zahl nicht auf.... das Register hat einfach 32bit... auch wenn die alle Null sind... das Register passt seine Breite nicht an...

der push Befehl bezieht sich auf 4 Bytes... egal, wieviele davon Null sind...

RedDevil1982 
Beitragsersteller
 29.05.2023, 22:26
@LUKEars

Ok, werden dann auf einmal die 11 47 00 00 auf den Stack gepusht oder

die 11 zuerst, dann die 47, dann die 00 und dann die letzten 00?

LUKEars  29.05.2023, 22:30
@RedDevil1982

das weiß nur die Firmware der CPU... die kann sich auch noch von Tag zu Tag ändern... es kann sein, dass der Stack Pointer nur ge-dec-t werden kann... dann wäre es Byte-weise... wenn man den Stack Pointer sub-en kann, und wenn man mis-align-t in den Hauptspeicher schreiben kann, dann kann man auch alle 4 Bytes auf einmal auf die Rutschbahn schicken....

RedDevil1982 
Beitragsersteller
 29.05.2023, 22:33
@LUKEars

Es geht mir hier ja um meine Aufgabe: Dort steht: "..skizzieren Sie den Byte-weisen Aufbau des Stacks nach dem zweiten push Befehl"

Siehe ganz oben!

=> Genau deshalb stelle ich die vorangegangene Frage:
Ob die Bytes einzeln auf den Stack gepusht werden oder nicht?

LUKEars  29.05.2023, 22:36
@RedDevil1982

du sollst nicht den Vorgang des push-ens skizzieren.... sondern den Zustand des Stack nach dem push-en...

siehst du den Unterschied?

LUKEars  29.05.2023, 22:43
@RedDevil1982

es könnte übrigens sein, dass ESP auf das zuletzt in den Stack geschriebene Byte zeigt... dann hättest du aber nichts in den zweiten Kasten von oben schreiben dürfen (also in den auf den „esp“ zeigt)...