user4929293 user4929293 - 24 days ago 6
C Question

using scanf function with asm language

extern printf
extern scanf
global main

section .text
main:
sub rsp, 0x10
mov rbx, rsp
add rbx, 0x08
mov rdi, format1
mov rsi, rbx
xor rax, rax
call scanf
mov rdi, format2
mov rsi, [rbx]
xor rax, rax
call printf
add rsp, 0x10
ret
format1:
db "%d", 0
format2:
db "%d", 0xa, 0
value:
dd 0xa


Above source is same with

#include <stdio.h>
int main(void)
{
int tmp;
scanf("%d", &tmp);
printf("%d\n", tmp);
}


It works well. But I have question. If I change my source code to

extern printf
extern scanf
global main

section .text
main:
mov rdi, format1
mov rsi, value
xor rax, rax
call scanf
mov rdi, format2
mov rsi, [value]
xor rax, rax
call printf
ret
format1:
db "%d", 0
format2:
db "%d", 0xa, 0
value:
dd 0xa


it makes segmentation fault. I think there are no difference between above source code and first one. Did I misunderstand?

Answer

In the first code, you're allocating space for a variable (the tmp in your C code, unnamed in the asm code) on the stack and passing the address of it to the scanf function, then passing the value that scanf wrote there to printf.

In the second, you're trying to use a global value allocated in the .text section instead, but .text is read-only by default on most systems. So when scanf tries to write to it, you get a segfault.

Stick a section .data just before value: to put it in the data section instead and it should be fine...