4

I'm trying to convert a user inputted string of numbers to an integer.

For example, user enters "1234" as a string I want 1234 stored in a DWORD variable.
I'm using lodsb and stosb to get the individual bytes. My problem is I can't get the algorithm right for it. My code is below:

mov ecx, (SIZEOF num)-1
mov esi, OFFSET num
mov edi, OFFSET ints
cld

counter:
   lodsb
   sub al,48
   stosb
   loop counter

I know that the ECX counter is going to be a bit off also because it's reading the entire string not just the 4 bytes, so it's actually 9 because the string is 10 bytes.

I was trying to use powers of 10 to multiply the individual bytes but I'm pretty new to Assembly and can't get the right syntax for it. If anybody can help with the algorithm that would be great. Thanks!

glennsl
  • 28,186
  • 12
  • 57
  • 75
Cody
  • 41
  • 1
  • 2

1 Answers1

1

A simple implementation might be

    mov ecx, digitCount
    mov esi, numStrAddress

    cld                     ; We want to move upward in mem
    xor edx, edx            ; edx = 0 (We want to have our result here)
    xor eax, eax            ; eax = 0 (We need that later)

counter:
    imul edx, 10            ; Multiply prev digits by 10 
    lodsb                   ; Load next char to al
    sub al,48               ; Convert to number
    add edx, eax            ; Add new number
    ; Here we used that the upper bytes of eax are zeroed
    loop counter            ; Move to next digit

    ; edx now contains the result
    mov [resultIntAddress], edx

Of course there are ways to improve it, like avoiding the use of imul.

EDIT: Fixed the ecx value

sannaj
  • 360
  • 2
  • 8
  • [The `loop` instruction is slow on most CPUs](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently); just use `dec` / `jnz`, or branch on flags set by `sub al, 48` (to stop after loading a non-digit character). You could use `lea edx, [rdx + rax]` to add without affecting flags. And yeah, since you can use LEA to shift-and-add, you can do `edx = eax + edx*10` with 2 LEA instructions. gcc makes good code for loops like this. – Peter Cordes Oct 15 '17 at 02:20