-1

In this code the user is asked to supply a number.
Once they do so the number should be incremented by 1.
This code works when you hard code the value of the number on line 11 (movq $number , %rsi).

If I replace "$Number" with an actual digit like "$5" for example the code will print out the value +1 so in this case '6', but it doesn't seem to work, can someone advise what i am doing wrong? /////////////////////////////////////////////////////////////////// updated code //////////////////////////////////////////////////////////// now works if user input is between 0-9 however errors start if input value > 10


.data
number: .skip 8

.text
mystring: .asciz "Your number +1 is = %d"

.global main
main:
    call _getNumber
    movq $0 , %rax
    movq number, %rsi
    sub $2608, %rsi
    inc %rsi
    movq $mystring, %rdi
    call printf
    ret

_getNumber:                 #sub routine to take number from the user
    movq $0, %rax           #set to 0 for input
    movq $0, %rdi
    movq $number, %rsi
    movq $8, %rdx
    syscall
    ret
  • You're reading 8 ASCII digits with a `read` system call, not a binary integer. Subtracting 2608 is probably `('\n'<<8) | '0'`, but without multiplying by place-values that can only work for single-digit integers. [Convert from ascii to integer in AT&T Assembly](https://stackoverflow.com/q/32034178) – Peter Cordes Mar 22 '22 at 20:11

1 Answers1

0

movq $number, %rsi puts the address of number into %rsi. That's what you want for reading. (Though you will get the bytes of the user input as binary, which is probably not what you want, e.g. if the user types 5 you will probably get the value 53. You have to do the conversion from ASCII decimal to binary by yourself, or by calling an appropriate library function like scanf or strtol. Separate project.)

But for calling printf you don't want the address of number, you want its contents. So in main you ought to have movq number, %rsi, which is AT&T syntax for a load from memory.

In C terms, movq $number, %rsi does rsi = &number;. Whereas movq number, %rsi does rsi = number;.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • Since this is x86-64, a `mov number(%rip), %rsi` is the canonical way to load from a label. Also, this code is using a `read` system call to read 8 bytes of string data into `number`, so another problem is using `%d` instead of `%s`. In that case you would want the address. – Peter Cordes Mar 22 '22 at 18:23
  • True, and likewise `mov $number, %rsi` in the `read` should be `lea number(%rip), %rsi`. But one thing at a time. – Nate Eldredge Mar 22 '22 at 18:24
  • Hi all, and thanks so much for your advice. I have edited my code as per some of your instruction and I can see that I am on the right track but still have 1 small issue. I can now see that as i enter the number 1 into my program i get the value of '2610' if i enter 2 into my program the output is '2611' how can i properly reduce this so the output value == inputValue +1? – Alexander Kearns Mar 22 '22 at 19:52
  • @AlexanderKearns: You need to do a proper decimal to binary conversion. See https://stackoverflow.com/questions/19309749/nasm-assembly-convert-input-to-integer for an example. – Nate Eldredge Mar 23 '22 at 14:45
  • @AlexanderKearns: Following the `read`, don't be thinking of the contents of `number` as actually being a number yet. It's just a sequence of 8 bytes, each containing one of the values 0x30-0x39 (ASCII codes for the characters `0` through `9`). Maybe the last one is 0x0a, line feed. It's your job to do the math to convert that sequence of digits into an actual (binary) number, before you can do any arithmetic on it. – Nate Eldredge Mar 23 '22 at 14:49