Assembly で次の C コードを記述します。
int main(void)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d%d",x,y);
return 0;
}
まず、スキャン/印刷する整数を 1 つだけ使用してみました。
.section .rodata #read only data section
fmt: .string "%d%d"
.text
.globl main
.type main, @function
main:
pushl %ebp #save the old frame pointer
movl %esp, %ebp #create the new frame pointer
pushl %esp #location of x
pushl $fmt
call scanf
#stack should now have exactly the scanned number x and then the format, as needed for printf.
call printf
movl $0, %eax
movl %ebp, %esp #restore the old stack pointer - release all used memory.
popl %ebp #restore old frame pointer (the caller function frame)
ret
しかし、うまくいきませんでした。何らかの理由で、次のトリックが機能しました(printfの前に追加されました):
addl $4,%esp #pop format
pushl 4(%esp)
pushl $fmt
pushl 4(%esp) が機能する理由がわからないので、最初の質問でその点について説明を求めています。次に、2 つの変数を使用して同じことを試みました。
fmt: .string "%d%d"
[...]
pushl %esp #location of x
pushl %esp #location of y
pushl $fmt
call scanf
しかし、それはセグメンテーションエラーを引き起こしました。次のようなことを試みたであろうprintf部分にも到達しませんでした:
addl $4,%esp #pop format
pushl 8(%esp)
pushl 8(%esp)
pushl $fmt
call printf
(以前の pushl 4(%esp) と同じロジックに従います。私の 2 番目の質問は、2 つの変数で機能させるにはどうすればよいかということです。ありがとう!
編集: 2 つの変数をスキャンするために次のコードが機能しないのはなぜですか?
subl $8,%esp #leave place for two vars
pushl -4(%ebp) #location of x
pushl -8(%ebp) #location of y
pushl $fmt
call scanf