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.


Anmelden zum Antworten