1

I've code that should parse String format to int but it changes f.e. 0 to 658688 and I don't know what to do with it. Is the lodsd command correct here?

toparse DB 128 dup(?)
mov toparse, "0"

  atoi proc uses esi edx inputBuff:DWORD
mov esi, inputBuff
xor edx, edx
.Repeat
lodsd
.Break .if !eax
imul edx, edx, 10
sub eax, "0"
add edx, eax
.Until 0
mov EAX, EDX
ret
  atoi endp

it returns 658688

4
  • x86.renejeschke.de/html/file_module_x86_id_160.html ... lodsd may be correct, if your string encoding is UTF-32 or other 4 byte encoding. It probably is not, as do mov toparse, "0". Did you check in debugger, what is happening? It's difficult to read your source, as it's not pure assembly, I think there are some macros or something... or are those "todo" comments maybe. Commented Dec 27, 2016 at 22:56
  • 1
    @ped These are not comments. The code uses MASM's high-level assembly syntax. I guess they are like macros, but they're built into the assembler. Commented Dec 28, 2016 at 7:51
  • 2
    lodsd is wrong. It loads a double-word (DWORD), but your characters are obviously byte-sized, since you've declared a string array using DB (Declare Byte). You probably want lodsb. Commented Dec 28, 2016 at 8:09
  • Your result value 658688 in hex is 0x0A0D00, so the good news is your code works (the low byte is 0, as intended). I bet the other two bytes came from your input routine: the Enter that you ended it with. So if you are going to adjust for a loop, either test for the of end your input string, or check each character to see it's a digit, in this routine. Commented Dec 28, 2016 at 14:18

1 Answer 1

1

You need to either invoke the atoi proc with the ascii's memory offset or push the offset before calling atoi. Right now esi will just contain the random values that are already in inputbuff.

I have revised the proc so that it will process full strings successfully.

toparse db "12345678",0

;mov toparse,"0" ; Max is 4 bytes so define string above

push offset toparse ; |
call atoi           ; - or: invoke atoi,offset toparse  

...

atoi proc uses esi inputBuff:DWORD ; Generally only need to preserve esi, edi and ebx
mov esi,inputBuff
xor edx,edx
xor eax,eax         ; Clear register
.Repeat
lodsb               ; Get one byte
.Break .if !eax
imul edx,edx,10     ; Multiply total by 10
sub eax,"0"         ; Subtract 48
add edx,eax         ; Add result to the total
.Until 0
mov eax,edx         ; Will result in 00BC614E (hex 12345678)
ret
atoi endp
Sign up to request clarification or add additional context in comments.

5 Comments

lodsd loads 4 bytes and increments ESI by 4. Unless your characters are stored as UTF-32, that's not going to work. You should either zero EAX ahead of the loop and use LODSB, or use movzx eax, byte [esi] / inc esi (which is only 2 uops instead of 3 for LODSB on recent Intel CPUs).
Also, your code still falls into atoi after the call returns. But good point about having to use a call to put args where MASM's macro-like stuff loads it from for mov esi, inputBuff. IMO that just makes it harder to see what's really happening vs. mov esi, [ebp+8] (or [esp+4] if you didn't make a stack frame).
So you're saying your code works, but only for a single-digit number? And LODSD zeroes the rest of EAX by loading zeros from the next three bytes, including 2 bytes past the end of the buffer? That will break as soon as you include this code in a program that has anything else in its data section, since then you can't count on the bytes after the buffer being zero.
That's a much more useful answer for the OP and for all future readers (which is the real point of SO). +1
These string-to-integer questions usually have a bunch of other bugs, so they don't make good targets for closing other questions as duplicates. This one actually does work well as a canonical string-to-integer question, and isn't full of 16-bit DOS I/O code or anything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.