#inline assembly scanf

11 messages · Page 1 of 1 (latest)

glacial helm
#

i was trying to do scanf in the inline assembly function but it kept giving me 0 or segfault. any ideas? i want to read the %d from rax, put the result of the scanf into rcx, and then it will assign rcx to out via the =c

int bruh() {
  int out;
  char * x = "%d";
  asm(
"mov %%rax, %%rdi;"
"mov %%rcx, %%rsi;"
"mov $0, %%al;"
"call scanf;"

: "=c" (out)
: "a" (x)
  );
  return out;
}

void main() {
  printf("val: %d\n", bruh());
}
```i expect the output ```
val: 32
``` given the stdin of `32`
here is the tio link https://tio.run/##PY9BCoMwEEX3OcWQNpAUW0q709qTdDOdaA3EWGIUoXh2m6C4mnkPhv@Hzh@iZTkYR3bQFTz6oE13aZ6MGRfg7YdGKvgxgITdEIq4UoMeTjBBCVxonhT2rWS87UYQwuOUpaFNwXdHq@t3d7wmgTYxobXQE7o6EsuBl8RBxjSVAOM@qRiiUpKvwuDdWmVmbOyMhhaN22p@fSxaSz6izUHol@PZ9kW8npflfvsD
keen lightBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

glacial helm
#

i have a similar working code using printf ```c
int bruh() {
int out;
char * x = "val: %d\n";

asm(
"mov %%rax, %%rbx;"
"mov %%rax, %%rdi;"
"mov $5, %%rsi;"
"mov $0, %%al;"
"call printf;"

: "=b" (out)
: "a" ("val: %d\n")
);
return out;
}

void main() {
printf("ebx: %d\n", bruh());
printf(bruh(), 32);
}

remote path
#

if you would use scanf("%d", ...) in normal C it expects an pointer to int as second argument (so you'd do scanf("%d", &out); to read an integer to out). When translating this to assembly you want to pass the address of"%d" (x) in %rdi and &out in %rsi. Both are just input values because the actual output is going to be written to the address %rsi is pointing to. So the code would look like this: ```c
asm(
"mov %%rax, %%rdi;"
"mov %%rcx, %%rsi;"
"mov $0, %%al;"
"call scanf;"
: /* no output variables */
: "a" (x), "c" (&out)
);

You could also let the compiler put all the values to the right registers: ```c
asm(
  "call scanf;"
  : /* no output variables */
  : "D" (x), "S" (&out), "a" (0) /* "D" means di register and "S" si register */
);
#

@glacial helm

glacial helm
#

thanks it works. is it possible to grab address rsi is pointing to as an output or use the out inside of the asm after scanf @remote path

keen lightBOT
#

@glacial helm Has your question been resolved? If so, run !solved :)

glacial helm
#

hm i copied some code from godbolt and i think it worked ```c
int main() {
int x;
int out;
asm(
"movl %%eax, -12(%%rbp);"
"leaq -12(%%rbp), %%rax;"
"movq %%rax, %%rsi;"
"movl %%ecx, %%edi;"
"movl $0, %%eax;"
"call scanf;"
"movl -12(%%rbp), %%eax;"
"addl $69, %%eax;"

: "=a" (out)
: "a" (x), "c" ("%d")
);
printf("%d", out);
}

keen lightBOT
#

This question thread is being automatically closed. If your question is not answered feel free to bump the post or re-ask. Take a look at !howto ask for tips on improving your question.

glacial helm
#
int main() {
asm(
  "lea -800(%%rbp), %%rax;"
  "mov %%rax, -800(%%rbp);" 
  "mov %%rcx, -1600(%%rbp);"
  "mov -1600(%%rbp), %%rdi;"
  "mov -800(%%rbp), %%rsi;"
  "mov $0, %%al;"
  "call scanf;"
  "mov -800(%%rbp), %%rax;"
  "add $69, %%rax;"
  "mov %%rax, -800(%%rbp);"
  "mov -1600(%%rbp), %%rdi;"
  "mov -800(%%rbp), %%rsi;"
  "mov $0, %%al;"
  "call printf;"
  :
  : "c" ("%d")
);
}
``` is a full program if anyone is curious
#

!solved