2012-06-11 3 views
13

Ich kann das nicht herausfinden. Ich bin offensichtlich wirklich neue Assembly, und ich versuche herauszufinden, wie Scanf verwenden, um Benutzereingaben zu erhalten.Wie verwende ich Scanf in NASM?

Ich weiß Printf verwenden alles, was ich tun muß, ist die Daten schiebt ich wie diese auf dem Bildschirm in den Stapel schreiben will:

global _main 
extern _printf 
extern _scanf 

section .data 
msg db "Hi", 0 

section .text 
_main: 
    push ebp 
    mov ebp, esp 

    push msg 
    call _printf 

    mov esp, ebp 
    pop ebp 
ret 

Aber ich kann nicht herausfinden, wie Scanf zu verwenden. Kann mir bitte jemand einfach den einfachsten Quellcode für Scanf geben? Ich möchte wirklich nur setzen, was der Benutzer eingibt.

Ich bin nicht zu 32bit Assembly gewöhnt. Ich habe immer nur 16-Bit verwendet wird, und ich weiß, in 16bit (DOS) können Sie diese gerade tun: „Eingang“

mov ah, 3fh 
mov dx, input 
int 21h 

input rb 100d 

Und was auch immer Sie die platziert an der Adresse eingeben wird

Bitte tragen Sie mit mir. Ich versuche das herauszufinden.

Antwort

15

Ich fand diese 'Programming in NASM.PDF'

; add1.asm 
SECTION .data 
    message1: db "Enter the first number: ", 0 
    message2: db "Enter the second number: ", 0 
    formatin: db "%d", 0 
    formatout: db "%d", 10, 0 ; newline, nul terminator 
    integer1: times 4 db 0 ; 32-bits integer = 4 bytes 
    integer2: times 4 db 0 ; 
SECTION .text 
    global _main 
    extern _scanf 
    extern _printf  

_main: 

    push ebx ; save registers 
    push ecx 
    push message1 
    call printf 

    add esp, 4 ; remove parameters 
    push integer1 ; address of integer1 (second parameter) 
    push formatin ; arguments are right to left (first parameter) 
    call scanf 

    add esp, 8 ; remove parameters 
    push message2 
    call printf 

    add esp, 4 ; remove parameters 
    push integer2 ; address of integer2 
    push formatin ; arguments are right to left 
    call scanf 

    add esp, 8 ; remove parameters 

    mov ebx, dword [integer1] 
    mov ecx, dword [integer2] 
    add ebx, ecx ; add the values   ; the addition 
    push ebx 
    push formatout 
    call printf       ; call printf to display the sum 
    add esp, 8        ; remove parameters 
    pop ecx 
    pop ebx ; restore registers in reverse order 
    mov eax, 0 ; no error 
    ret 

Welche der asm-Version dieser C-Funktion ist:

#include <stdio.h> 
int main(int argc, char *argv[]) 
{ 
    int integer1, integer2; 
    printf("Enter the first number: "); 
    scanf("%d", &integer1); 
    printf("Enter the second number: "); 
    scanf("%d", &integer2); 
    printf("%d\n", integer1+integer2); 
    return 0; 
} 
+0

Hmm, danke, das hilft. Ich werde auch in das PDF schauen. – user1432532

+0

Wo ist der Assembler-Code für die Anweisung printf ("% d \ n", Integer1 + Integer2)? – azurkin

+0

@azurkin - Gut entdeckt. Es ist in der PDF-Datei und ich habe es hinzugefügt –

3

Dank Preet. Ich habe ein einfaches Beispiel basierend auf Ihrem Code erstellt, um die Verwendung von scanf zu veranschaulichen.

Programm, das eine ganze Zahl anfordert und druckt sie auf dem Bildschirm aus:

section .text 
    global main 
    extern printf 
    extern scanf 

section .data 
    message: db "The result is = %d", 10, 0 
    request: db "Enter the number: ", 0 
    integer1: times 4 db 0 ; 32-bits integer = 4 bytes 
    formatin: db "%d", 0 

main: 
    ; Ask for an integer 
    push request 
    call printf 
    add esp, 4 ; remove the parameter 

    push integer1 ; address of integer1, where the input is going to be stored (second parameter) 
    push formatin ; arguments are right to left (first parameter) 
    call scanf 
    add esp, 8 ; remove the parameters 

    ; Move the value under the address integer1 to EAX 
    mov eax, [integer1] 

    ; Print out the content of eax register 
    push eax 
    push message 
    call printf 
    add esp, 8 

    ; Linux terminate the app 
    MOV AL, 1 
    MOV EBX, 0 
    INT 80h 
0

Lassen Sie uns sagen Sie so etwas wie

scanf("%d %d", &var1, &var2); 

Das nimmt zwei Werte und speichert sie in den Variablen tun wollen.

In Assembly würden Sie push die Adressen der Variablen in den Stapel (in umgekehrter Reihenfolge) und dann call scanf.

So etwas wie Sie zwei Variablen

haben ... und dann

push var2 
push var1 
call scanf 

* Beachten Sie, dass ich sie in nach hinten geschoben, wird der erste Wert in var1 gespeichert werden.

Nach der Ausführung werden die von Ihnen eingegebenen Werte in den Variablen gespeichert.

Wenn Sie nur einen Wert wünschen, drücken Sie einfach eine Variable.

+0

Vergessen Sie nicht, den Stapel nach der Rückkehr scanf Pop. ('add esp, 8' für 32-bit code, oder' add rsp, 16' für 64-bit). –

1

Dies ist der erste Beitrag, der angezeigt wird, wenn Sie in Assembly nach scanf suchen, also, auch wenn es ein 4 Jahre alter Beitrag ist, denke ich, dass es korrekt sein sollte.

Oukei, so zu call scanf in NASM Montage müssen Sie:

  1. Extern Scanf
  2. ein formatation Bereiten Sie
  3. die Variablen oder einzelne Variable vorbereiten scanf die Werte speichern erwartet
  4. Die Parameter in umgekehrter Reihenfolge drücken
  5. Anruf scanf
  6. Wiederherstellungsstapel

So können, sagen Sie traying zu

scanf ("%d %d", &val1, &val2); 

und im Anschluss an die Liste:
... 1.

section .text 
extern scanf 

... 2. Dies ist der erste Parameter, den Sie an Ihre C scanf übergeben, es sagt, was Sie bekommen werden. Eine ganze Zahl, zwei, ein Schwimmer, string, char ... In diesem Fall zwei ganze Zahlen durch ein Leerzeichen getrennt (funktioniert auch mit Enter)

section .data 
fmt: db "%d %d",0 

... 3.

section .bss 
val1: resd 1 
val2: resd 1 

... 4 5 6. beachten Sie, dass die Adresse der Variablen schieben, nicht ihr Inhalt (dh [var])

push val2 
push val1 
push fmt 
call scanf 
add esp, 12 

beachten Sie auch, dass Sie 12 auf den Stapelzeiger hinzuzufügen, weil Sie 3 geschoben Doppelw rd Parameter. Sie fügen also 12 Bytes (3 * 4 Bytes) zum Stack hinzu, um die Parameter zu "springen".

* Ich deklarierte DWORD für die Variablen, weil %d DWORD verwendet, wie printf.
** Die ,0 am Ende der Formatierungszeichenfolge ist ein Sentinel-Zeichen.

+0

Sie können Ihre Konten zusammenführen (suchen Sie auf [meta], um herauszufinden, wie). Oder Sie können Ihre vorherige Antwort von Ihrem anderen Konto löschen, da es sowieso keine Upvotes gibt. Und bitte [bearbeiten] Sie diesen, um eigenständig zu bleiben, anstatt auf Ihren anderen Beitrag zu verweisen. –

+0

Ich habe als Gast mit dem Namen PunditPoe geantwortet, kann nicht herausfinden, ob ich diesen Gastaccount "eintragen" und den Beitrag löschen kann. Aber ich habe diesen hier korrigiert, um alleine zu stehen. Vielen Dank. –