App installieren
How to install the app on iOS
Follow along with the video below to see how to install our site as a web app on your home screen.
Anmerkung: This feature may not be available in some browsers.
Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden.
Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Assembler + Stack
- Ersteller hasufel
- Erstellt am
Hi ho!
Ich versuche gerade mich in Assembler einzuarbeiten (IA32, nasm).
Leider scheinen die meisten Tutorials und mein Script für Leute mit C-Kentnissen zu sein. Habe bisher nur ein wenig Java programmiert. Ich scheitere schon an der ersten Aufgabe, da mir nicht klar ist wie ich bedingte Sprünge anwende und was dabei mit dem Stack und passiert:
Das Programm add64.asm soll 2 64bit Zahlen addieren. Der höherwertige Teil des ersten Summanden soll in EAX, der niederwertige in EBX gespeichert werden. Der 2. Summand entsprechend in ECX und EDX.
Das Ergebniss soll in EAX und EBX gespeichert werden.
Die Summanden habe ich als statische Variablen eingetragen, um mir erstmal i/o zu ersparen:
Section .data ; for static variables and buffers
a: dd 0x11111111 ; eax
b: dd 0x22222222 ; ebx
c: dd 0x33333333 ; ecx
d: dd 0x44444444 ;edx
Diese lade ich in die Register:
mov eax, a ; eax -> a
mov ebx, b ; ebx -> b
mov ecx, c ; usw.
mov edx, d
Anschließend addiere ich die niederwertigen Teile der Summanden:
add ebx, edx
Dann müsste ich das OverflowFlag abfragen und falls dieses gesetzt ist eax incrementieren.
Doch wie mache ich das? Ich nehme an das ich einen bedingten Sprung (jo [jump overflow]) machen muss. Aber wohin springe ich? Muss ich ein Unterprogramm schreiben um die Zahl zu erhöhen und ggf falls dabei wieder zum überlauf kommt ein weiteres Unterprogramm eine Fehlermeldung ausgeben lassen?
Und was mache ich dabei mit dem Stack? Kann ich den so lassen wenn das Unterprogramm nur eax um 1 erhöht und sonst nicht auf die Register zugreift?
Fragen über Fragen
mfg hasu
Ich versuche gerade mich in Assembler einzuarbeiten (IA32, nasm).
Leider scheinen die meisten Tutorials und mein Script für Leute mit C-Kentnissen zu sein. Habe bisher nur ein wenig Java programmiert. Ich scheitere schon an der ersten Aufgabe, da mir nicht klar ist wie ich bedingte Sprünge anwende und was dabei mit dem Stack und passiert:
Das Programm add64.asm soll 2 64bit Zahlen addieren. Der höherwertige Teil des ersten Summanden soll in EAX, der niederwertige in EBX gespeichert werden. Der 2. Summand entsprechend in ECX und EDX.
Das Ergebniss soll in EAX und EBX gespeichert werden.
Die Summanden habe ich als statische Variablen eingetragen, um mir erstmal i/o zu ersparen:
Section .data ; for static variables and buffers
a: dd 0x11111111 ; eax
b: dd 0x22222222 ; ebx
c: dd 0x33333333 ; ecx
d: dd 0x44444444 ;edx
Diese lade ich in die Register:
mov eax, a ; eax -> a
mov ebx, b ; ebx -> b
mov ecx, c ; usw.
mov edx, d
Anschließend addiere ich die niederwertigen Teile der Summanden:
add ebx, edx
Dann müsste ich das OverflowFlag abfragen und falls dieses gesetzt ist eax incrementieren.
Doch wie mache ich das? Ich nehme an das ich einen bedingten Sprung (jo [jump overflow]) machen muss. Aber wohin springe ich? Muss ich ein Unterprogramm schreiben um die Zahl zu erhöhen und ggf falls dabei wieder zum überlauf kommt ein weiteres Unterprogramm eine Fehlermeldung ausgeben lassen?
Und was mache ich dabei mit dem Stack? Kann ich den so lassen wenn das Unterprogramm nur eax um 1 erhöht und sonst nicht auf die Register zugreift?
Fragen über Fragen
mfg hasu
Da ist ein kapitaler Fehler drinnen, so müsste es aussehen:
Die eckigen Klammern sind wichtig, sonst wird nur das Offset in das Register geladen - nicht der Inhalt an diesem Offset.
Dann einfach weiter
Nun überprüfst du das Overflow Flag, mit dem bedingten Sprung JNO (Jump if No Overflow). Tritt ein Überlauf auf, setzt der ADD Befehl das Overflow Flag - JNO guckt, ob das Flag gesetzt ist - wenn nicht, wird zur angegebenen Adresse gesprungen.
Die 64bit Zahl liegt jetzt in ECX:EAX
PS Den Stack brauchst du hier nicht angucken. Es sei denn, du willst ein echtes Unterprogramm draus machen, das du per CALL aufrufen kannst - dann greifst du aber auch nur indirekt auf den Stack zu, sprich hast damit keinen direkten Kontakt (nur über CALL und RET).
Code:
MOV EAX, [A]
MOV EBX, [B]
MOV ECX, [C]
MOV EDX, [D]
Die eckigen Klammern sind wichtig, sonst wird nur das Offset in das Register geladen - nicht der Inhalt an diesem Offset.
Dann einfach weiter
Code:
ADD EAX, EBX
Nun überprüfst du das Overflow Flag, mit dem bedingten Sprung JNO (Jump if No Overflow). Tritt ein Überlauf auf, setzt der ADD Befehl das Overflow Flag - JNO guckt, ob das Flag gesetzt ist - wenn nicht, wird zur angegebenen Adresse gesprungen.
Code:
JNO NoOverflow
INC ECX
NoOverflow
ADD ECX, EDX
Die 64bit Zahl liegt jetzt in ECX:EAX
PS Den Stack brauchst du hier nicht angucken. Es sei denn, du willst ein echtes Unterprogramm draus machen, das du per CALL aufrufen kannst - dann greifst du aber auch nur indirekt auf den Stack zu, sprich hast damit keinen direkten Kontakt (nur über CALL und RET).
Zum Verständnis was es mit den Labels etc. auf sich hat, kannst du ein paar einfachere Programme als binär assemblieren (Standardausgabeformat von nasm, die anderen Formate enthalten noch diverse Verwaltungsinformationen, die aber eher für einen linker wichtig sind), und dir per ndisasm angucken was da eigentlich rausgekommen ist.
Labels werden einfach zur Adresse aufgelößt, in der du das Label definiert hast. Also statt MOV EAX, [A] steht dann sowas im Programm wie MOV EAX, [0x0]; MOV EBX, [0x4] etc. - genauso bei Sprüngen, also im Endeffekt steht da nur noch JNO 0x12345, wobei 0x12345 die Adresse ist, an der du das Label NoOverflow definiert hast.
In dem Zusammenhang ist auch noch ORG interessant, ladt dir am besten einfach die nasm manual runter, da ist auch eine Referenz zu allen Befehlen bei.
Labels werden einfach zur Adresse aufgelößt, in der du das Label definiert hast. Also statt MOV EAX, [A] steht dann sowas im Programm wie MOV EAX, [0x0]; MOV EBX, [0x4] etc. - genauso bei Sprüngen, also im Endeffekt steht da nur noch JNO 0x12345, wobei 0x12345 die Adresse ist, an der du das Label NoOverflow definiert hast.
In dem Zusammenhang ist auch noch ORG interessant, ladt dir am besten einfach die nasm manual runter, da ist auch eine Referenz zu allen Befehlen bei.
Danke für die Tips! Werd ich wohl auch brauchen - in den nächsten Wochen kommt noch einiges auf mich zu: Aufgaben
Für die Ausgabe muss ich die Hexadezimalzahlen in Ascci umwandeln - das heisst wohl ich muss überprüfen ob 4bits einem Wert größer 9 entsprechen oder nicht, und anschließend die Differenz zum jeweiligen Ascii-Zeichen aufaddieren.
Wegen dem disassembler - das kann ich wohl nur, wenn die Programme auf den Intel-Rechnern installiert sind. Hab zuhause einen AMD-Rechner. Ich wusste erst garnicht wie ich die Aufgaben machen sollte, da ich in der uni auch keinen Zugang zu dem Rechnerraum habe. Aber dafür gibts ja ssh ; ) Das ist via DSL ganzschön langsam (bin kein Fan von vi und benutze einen grafischen debugger). Gott sei Dank gibts noch die langsamen SunTerminals - die Räume sind fast immer frei und wenn ich eh auf ner anderen Kiste angemeldet bin ist es ja egal wie langsam die sind.
mfg hasu
Edit: goil - alles da!
Vielen Dank nochmal!
Für die Ausgabe muss ich die Hexadezimalzahlen in Ascci umwandeln - das heisst wohl ich muss überprüfen ob 4bits einem Wert größer 9 entsprechen oder nicht, und anschließend die Differenz zum jeweiligen Ascii-Zeichen aufaddieren.
Wegen dem disassembler - das kann ich wohl nur, wenn die Programme auf den Intel-Rechnern installiert sind. Hab zuhause einen AMD-Rechner. Ich wusste erst garnicht wie ich die Aufgaben machen sollte, da ich in der uni auch keinen Zugang zu dem Rechnerraum habe. Aber dafür gibts ja ssh ; ) Das ist via DSL ganzschön langsam (bin kein Fan von vi und benutze einen grafischen debugger). Gott sei Dank gibts noch die langsamen SunTerminals - die Räume sind fast immer frei und wenn ich eh auf ner anderen Kiste angemeldet bin ist es ja egal wie langsam die sind.
mfg hasu
Edit: goil - alles da!
Code:
[gspaltho@bonete03 Assembler]$ ndisasm add64.bin
00000000 66A13400 mov eax,[0x34]
00000004 668B1E3800 mov ebx,[0x38]
00000009 668B0E3C00 mov ecx,[0x3c]
0000000E 668B164000 mov edx,[0x40]
00000013 6601D3 add ebx,edx
00000016 7302 jnc 0x1a
00000018 6641 inc ecx
0000001A 6601C8 add eax,ecx
0000001D CD80 int 0x80
0000001F C3 ret
00000020 90 nop
00000021 E8DCFF call 0x0
00000024 66B801000000 mov eax,0x1
0000002A 66BB00000000 mov ebx,0x0
00000030 CD80 int 0x80
00000032 0000 add [bx+si],al
00000034 1111 adc [bx+di],dx
00000036 1111 adc [bx+di],dx
00000038 2222 and ah,[bp+si]
0000003A 2222 and ah,[bp+si]
0000003C 3333 xor si,[bp+di]
0000003E 3333 xor si,[bp+di]
00000040 EE out dx,al
00000041 EE out dx,al
00000042 EE out dx,al
00000043 EE out dx,al
Vielen Dank nochmal!
Zuletzt bearbeitet:
Öhm... was du da programmierst ist x86 Assembler, genauer IA32 Assembler - der läuf sowohl auf Intel, als auch auf AMD Plattformen. Sonst wären AMD CPUs keine x86 CPUs .
Für die Aufgaben fehlt username und passwort.
Für die Aufgaben fehlt username und passwort.
Hm, dachte das die Syntax prozessorspezifisch ist. Wenn ich die gleiche Menmonik anwenden kann wäre das sehr kewl. Hab schon überlegt ob ich nen alten Celeron wieder ausgrabe um auch nach dem Kurs weiter assemblieren zu können.
Sorry, der Link war falsch.
hier nochmal der richtige (nur falls es dich interessiert).
Die Scripte gibts leider nur mit PW. Ich nehme an, das liegt daran das da einiges aus Lehrbüchern übernommen wurde.
Die Scripte sind für dich warscheinlich eh uninteressant - du weißt das ja alles schon
Den letzten Beitrag hatte ich nochmal editiert....
mfg hasufel
Edit: Wofür stehen die Nummern am Anfang der Zeile? Sind das relativen Adressen des ersten Bits eines Speicherplatzes im für das Programm reservierten Bereich?
Wenn ja, sollten die nicht durch 4 teilbare Startbits haben um am Stück ausgelesen werden zu können? Stichwort "Aligned"
btw: jetzt weiß ich endlich wo du wohnst Hatte es mir schon fast gedacht. Jetzt weiß ich es dank "/proc/ioports"
Sorry, der Link war falsch.
hier nochmal der richtige (nur falls es dich interessiert).
Die Scripte gibts leider nur mit PW. Ich nehme an, das liegt daran das da einiges aus Lehrbüchern übernommen wurde.
Die Scripte sind für dich warscheinlich eh uninteressant - du weißt das ja alles schon
Den letzten Beitrag hatte ich nochmal editiert....
mfg hasufel
Edit: Wofür stehen die Nummern am Anfang der Zeile? Sind das relativen Adressen des ersten Bits eines Speicherplatzes im für das Programm reservierten Bereich?
Wenn ja, sollten die nicht durch 4 teilbare Startbits haben um am Stück ausgelesen werden zu können? Stichwort "Aligned"
btw: jetzt weiß ich endlich wo du wohnst Hatte es mir schon fast gedacht. Jetzt weiß ich es dank "/proc/ioports"
Zuletzt bearbeitet:
Ist nix spezifisch, mit x86 Assembler kannst du jede x86 CPU programmieren. Spezifisches geht eigentlich garnicht, mal von den diversen Erweiterungen von x86 abgesehen - da gibts aber auch nur ein paar Sachen:
8086 - sind alle Befehle, die der 8086 kennt
8087 - der Befehlssatz der 8086 FPU
286 - ein paar zusätzliche Befehle, die der 286 kennt, 16bit Protected Mode
386 - 32bit Register im Real Mode, ein größerer Batzen neuer Anweisungen und der komplette Protected Mode
387 - ein paar neue FPU Befehle
486 - ein oder 2 neue Befehle im Real- und Protected Mode
586 - wieder ein oder 2 neue Befehle im Real- oder Protected Mode
MMX
CMMX
686 - selbes Spielchen nochmal
SSE1/2/3
3DNow, 3DNow Prof
Seit dem Pentium Pro, dem Athlon und dem Cyrix 6x86MX kennen alle CPUs den 686 Befehlssatz. Und selbst einen 386er kannst du ohne Unterschiede zum 686 programmieren, die paar neuen Befehle braucht man eigentlich nur sehr sehr selten. Insgesammt sind im Protected Mode seit dem 386 vielleicht 10 neue Befehle aufgetaucht, die teilweise sehr komplexe Operationen ausführen.
Es gibt nur eine einzige CPU die man wirklich direkt programmieren kann, und das ist der NexGen 586. Alle anderen bekommen IA32 Assembler, der NexGen versteht sich natürlich auch auf IA32 Asm.
8086 - sind alle Befehle, die der 8086 kennt
8087 - der Befehlssatz der 8086 FPU
286 - ein paar zusätzliche Befehle, die der 286 kennt, 16bit Protected Mode
386 - 32bit Register im Real Mode, ein größerer Batzen neuer Anweisungen und der komplette Protected Mode
387 - ein paar neue FPU Befehle
486 - ein oder 2 neue Befehle im Real- und Protected Mode
586 - wieder ein oder 2 neue Befehle im Real- oder Protected Mode
MMX
CMMX
686 - selbes Spielchen nochmal
SSE1/2/3
3DNow, 3DNow Prof
Seit dem Pentium Pro, dem Athlon und dem Cyrix 6x86MX kennen alle CPUs den 686 Befehlssatz. Und selbst einen 386er kannst du ohne Unterschiede zum 686 programmieren, die paar neuen Befehle braucht man eigentlich nur sehr sehr selten. Insgesammt sind im Protected Mode seit dem 386 vielleicht 10 neue Befehle aufgetaucht, die teilweise sehr komplexe Operationen ausführen.
Es gibt nur eine einzige CPU die man wirklich direkt programmieren kann, und das ist der NexGen 586. Alle anderen bekommen IA32 Assembler, der NexGen versteht sich natürlich auch auf IA32 Asm.
Oh man, da hatte ich ein Brett vorm Kopf. Hätte ich auch selber drauf kommen können, zumal ich bei jeder Linux-installation damit konfrontiert wurde - x86 kompatibel....
Das die Befehle sich SO wenig unterscheiden hätte ich aber auch nicht gedacht.
mfg hasu
Das die Befehle sich SO wenig unterscheiden hätte ich aber auch nicht gedacht.
mfg hasu
Der 486 (oder wars 586?) bringt sogar nur einen neuen Befehl mit, nämlich CMPXCHG. In der Nasm Manual steht auch drinne, welche Generation den jeweiligen Befehl unterstützt - kann ich dir wirklich ans Herz legen, ist inzwischen auch mein Standard-Nachschlagewerk bei irgendwelchen Asm Fragen.
Oder du vertiefst dich in das Standartwerk schlechthin: The Art of Assembly Language
Da sind auch die Schritte vom 8086 bis zum 586 relativ gut erläutert, genauso solche Sachen wie die Branch Prediction, Pipelining, Superskalare Architekturen, Prefetch Queue, und und und.
Da sind auch die Schritte vom 8086 bis zum 586 relativ gut erläutert, genauso solche Sachen wie die Branch Prediction, Pipelining, Superskalare Architekturen, Prefetch Queue, und und und.
Ähnliche Themen
- Antworten
- 8
- Aufrufe
- 4K
- Antworten
- 0
- Aufrufe
- 142K
- Antworten
- 0
- Aufrufe
- 134K