Wert von StdIn nach eax
-
Hallo
Wenn ich bei StdIn z.b. 123 eingebe dann will ich die Zahl 123 ins eax Register schieben aber ich hab keine Ahnung wie das gehen soll
Kann man nicht irgendwie den Wert der an der Adresse von var steht in irgendein Register verschieben ?
.data var db 20 dup(0) .code start: invoke StdIn , addr var , 3 mov eax , offset var ; geht natürlich nicht
-
kann ja gar nicht gehen, ich sehe auch gar keine 123
Man kann in dem Zusammenhang der direkten und indirekten Speicheradressierung ziemlich durcheinanderkommen.
Der Code oben liest nach eax die Adresse von var.
...besser als nix, die könnte man nach z.B. esi kopieren und dann mit den entsprechenden Befehlen inhaltlich nach eax auslesen.
z.B. mit mov eax, [esi]
-
unter der Annahme, das auch wirklich nur ein integer eingegeben wird:
mov eax,SDWORD ptr [a2sd(offset var)]
a2sd ist hierbei ein macro, der sich der CRT Funktion sscanf bedient: hiermit wird in einem String nach einem integer gescannt.
-
nicht vergessen macros.asm ein zu binden:
include \masm32\macros\macros.asm
-
Oops ich hatte vergessen zu sagen das ich keine Macros verwenden will weil dann lernt man ja nix.
-
schau dir mal das an - es sollte dir zumindest eine Idee geben wie man eine Zahl aus einem String extrahiert:
a2dw_ proc uses esi edi ebx psz: ptr BYTE LOCAL signe:DWORD ;/* skip blanks */ mov esi,psz .while BYTE ptr [esi]== 20h || BYTE ptr [esi]== 9 lea esi,[esi+1] .endw ;/* negativ signe ? */ .if BYTE ptr [esi] == '-' mov signe,1 lea esi,[esi+1] .elseif BYTE ptr [esi] == '+' mov signe,0 lea esi,[esi+1] .else mov signe,0 .endif ;/* scan till end of numeric string */ xor ecx,ecx .while BYTE ptr [esi+ecx] >= '0' && BYTE ptr [esi+ecx] <= '9' lea ecx,[ecx+1] .endw ;/* convert lowest digit */ movzx ebx,BYTE ptr [esi+ecx-1] lea ebx,[ebx-'0'] lea ecx,[ecx-1] mov edi,10 ;/* convert digits */ .while ecx mov edx,edi movzx eax,BYTE ptr [esi+ecx-1] lea eax,[eax-'0'] mul edx add ebx,eax lea edi,[edi*4+edi] lea edi,[edi+edi] lea ecx,[ecx-1] .endw mov eax,ebx .if signe neg eax .endif ret a2dw_ endp
masm
-
Mhhm ich guck mir lieber mal an wie die Macros erstellt wurden
Aus der Datei masm32/macros/macros.asm
sval MACRO lpstring ; string to signed 32 bit integer invoke atol, reparg(lpstring) EXITM <eax> ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;, input MACRO prompt:VARARG LOCAL txt LOCAL buffer IFNB <prompt> .data txt db prompt, 0 align 4 .data? buffer db 132 dup (?) align 4 .code invoke StdOut,ADDR txt invoke StdIn,ADDR buffer,128 mov BYTE PTR [buffer+eax], 0 invoke StripLF,ADDR buffer EXITM <OFFSET buffer> ELSE .data? buffer db 132 dup (?) align 4 .code invoke StdIn,ADDR buffer,128 mov BYTE PTR [buffer+eax], 0 invoke StripLF,ADDR buffer EXITM <OFFSET buffer> ENDIF ENDM
Das erscheint mir leichter.
z.b. bei deinem Beispiel:
;/* skip blanks */ mov esi,psz .while BYTE ptr [esi]== 20h || BYTE ptr [esi]== 9 lea esi,[esi+1] .endw
Was ist ein blank ? Eine Leerstelle ? und wieso prüft der auf 20h oder 9 ?
-
ok, dachte du wolltest die Funktion selber implementieren. In diesem Fall kannst du auch gleich die Funktion atol verwenden - in diesem Zusammenhang am besten auch noch mal einen Blick in die Dokumentation werfen: \masm32\help\masmlib.chm
unter Blanks versteht man i.d.R. Leerzeichen und Tabulatoren.
(BTW: Gezeigt Funktion fehlt es im Übrigen noch an der Überprüfung auf einen leeren String)
-
prob schrieb:
Hallo
Wenn ich bei StdIn z.b. 123 eingebe dann will ich die Zahl 123 ins eax Register schieben aber ich hab keine Ahnung wie das gehen soll
Versuch auch mal diesen Code zu verstehen:
.data var db '123',13,10 d32 dd 0 .code xor eax, eax mov ecx, eax mov edx, offset var L: mov cl, [edx] sub cl, '0' js E cmp cl, 9 ja E push ecx shl eax, 1 mov ecx, eax shl eax, 2 add eax, ecx pop ecx add eax, ecx inc edx jmp L E: mov d32, eax ; d32 = 123 eax = 123
mfg
-
prob schrieb:
Was ist ein blank ? Eine Leerstelle ? und wieso prüft der auf 20h oder 9 ?
das ist ASCII-Code, dafür gibt es Übersichtstabellen, (wie z.B. http://www.code-knacker.de/ascii.htm ), sollte man sich Ausdrucken.