scanf
を使用してユーザー入力を取得する方法を理解しようとしています。私はprintf
を使用することを知っています。次のように、画面に書き込むデータをスタックにプッシュするだけです。
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
しかし、scanf
の使い方がわかりません。誰かがscanf
にできる最も簡単なソースコードを教えてくれませんか?私は本当にユーザーが入力したものを入れたいだけです。
私は32ビットアセンブリに慣れていません。私はこれまで16ビットしか使用していませんが、16ビット(DOS)では次のことができます。
mov ah, 3fh
mov dx, input
int 21h
input rb 100d
そして、入力したものは何でも「入力」のアドレスに配置されます。
私はこれを見つけました '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
このC関数のasmバージョンはどれですか。
#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;
}
Preetに感謝します。 scanfの使用法を説明するために、コードに基づいて簡単な例を作成しました。
整数を要求して画面に出力するプログラム:
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
これは、Assemblyでscanf
を検索したときに表示される最初の投稿なので、4年前の投稿であっても、正しいはずだと思います。
Oukei、つまり、NASMアセンブリの_call scanf
_には、次のことを行う必要があります。
だから、あなたがトレーにいるとしましょう
_scanf ("%d %d", &val1, &val2);
_
そして次のリスト:
... 1。
_section .text
extern scanf
_
... 2。これはCscanf
に渡す最初のパラメーターであり、何を取得するかを示します。 1つの整数、2つ、float、string、char ...この場合、スペースで区切られた2つの整数(Enterでも機能します)
_section .data
fmt: db "%d %d",0
_
... 3。
_section .bss
val1: resd 1
val2: resd 1
_
... 4 5 6.内容ではなく変数のアドレスをプッシュすることに注意してください(つまり、[var])
_Push val2
Push val1
Push fmt
call scanf
add esp, 12
_
また、3つのダブルWordパラメーターをプッシュしたため、スタックポインターに12を追加する必要があることに注意してください。したがって、12バイト(3 * 4バイト)をスタックに追加して、パラメーターを「ジャンプ」します。
* _%d
_はprintf
と同じようにdwordを使用するため、変数のdwordを宣言しました。
**フォーマット文字列の最後の_,0
_は、歩哨文字です。
あなたが次のようなことをしたいとしましょう
scanf("%d %d", &var1, &var2);
これは2つの値を取り、それらを変数に格納します。
アセンブリでは、変数のアドレスをスタックにPush
(逆順で)してからcall scanf
。
2つの変数があるようなもの
var1 resd 1
var2 resd 1
... その後
Push var2
Push var1
call scanf
*逆の順序でプッシュしたことに注意してください。最初の値はvar1に格納されます。
実行後、入力した値は変数に保存されます。
1つの値のみが必要な場合は、1つの変数をプッシュします。