0

I'v tried to run this code, and that what happend -

a. scanf want "epsilon = %lf"

b. for some reason, the program does not continue to print epsilon, but insted it's scan again for "order = %d"

c. print epsilon at that point

d. scanf again for "order = %d"

e. print the first order and exit

I would like to know why the program entered twice to scanf, and how to fix it =]

(there is a terminal img below, to see steps a-e in the actual program)

global main
extern printf 
extern scanf

section .data
    epsilon_formatIN: db "epsilon = %lf",10,0
    epsilon_formatOUT: db "epsilon = %lf",10,0
    order_formatIN: db "order = %d",10,0
    order_formatOUT: db "order = %d",10,0

section .bss
    epsilon: resq 1
    order: resb 1


section .text

   main:
     push rbp
     mov rbp, rsp
     mov rax, 0

     .get_epsilon:
      mov rdi, epsilon_formatIN
      mov rsi, epsilon
      mov rax, 0
      call scanf

    .print_epsilon:
      mov rdi, epsilon_formatOUT
      movsd xmm0, qword [epsilon]
      mov rax, 1    
      call printf


   .get_order:
     mov rdi, order_formatIN
     mov rsi, order
     mov rax, 0
     call scanf

   .print_order:
     mov rdi, order_formatOUT
     mov rsi, [order]
     mov rax, 0
     call printf

   pop rbp
   ret

terminal image after compiling and run this code:

terminal image after compiling and run this code

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
tzach94
  • 1
  • 3
  • Your scanf format string ends with trailing whitespace (`\n` aka newline, ASCII 10), so it keeps reading after the conversion until the first non-whitespace character. **Trailing space in the format string *doesn't* match a newline in the input.** This would have been more obvious if you single-stepped with a debugger. You'd see it's still all within the same scanf call. You could have made this a better [mcve] by reducing your code to only one `scanf`: your program runs scanf twice, so it took me a while to understand your problem. – Peter Cordes Apr 19 '18 at 14:21
  • Related: beware that `%f` and `%lf` for printf both mean `double`, not `float`. `%lf` works, but in asm you need to be aware of this because there's no C compiler doing the default conversions for you: [How to print a single-precision float with printf](//stackoverflow.com/q/37082784) – Peter Cordes Apr 19 '18 at 14:23
  • I want a double. I'v tried to remove the 10,0 after the scan format, and it just print the 2 formats afterwards and exit. I want the program to get an input, print it, and than get another. – tzach94 Apr 19 '18 at 14:28
  • I know you do. But using `%lf` for `double` implies that you think `%f` would work to `printf` a `float`. If you tried that, you'd have a problem. – Peter Cordes Apr 19 '18 at 14:30
  • Sorry for the lack of understanding from my side, but I still haven't quit yet get what I should change in my code for it to run properly. – tzach94 Apr 19 '18 at 14:42
  • Remove the `,10` from your scanf format strings. That's a newline, i.e. whitespace. – Peter Cordes Apr 19 '18 at 14:53
  • But than its print the epsilon, than print order = 0, and than exit, it doesn't do another scan. Why? – tzach94 Apr 19 '18 at 15:12
  • Oh right, you need *leading* whitespace at the start of the `order` format string to match the newline that the first scanf doesn't eat. Conversions like `%d` or `%s` skip whitespace, but literal non-whitespace text like `order` is considered a "directive" that doesn't skip whitespace. I added a section to the answer on [scanf() leaves the new line char in the buffer](//stackoverflow.com/q/5240789) about this special case. (It's really unusual to require the user to type in `order = 123` instead of just `123`, so that wasn't part of the original answer.) – Peter Cordes Apr 20 '18 at 00:35

0 Answers0