-1

I'm working on a function that picks a string, for example "input db '5', 0" and turns it into "input '53', 0" (an int). I have the following code. But everytime I run it outputs Segmentation Fault (core dumped).

stoi:
 push ebx

 mov ebx, eax

 stoiLoop:
  ; if is null: end
  cmp byte[ebx], 0
   call stlEnd

  ; if < 48: continue
  cmp byte[ebx], 48
   jl stlContinue

  ; if > 57: continue
  cmp byte[ebx], 57
   jg stlContinue

  ; add 48 so it matches the ascii code of number
  mov al, [ebx]
  add al, 48

  call stlContinue

 stlContinue:
  inc ebx
  call stoiLoop

 stlEnd:
  mov eax, ebx
  pop ebx
  ret

I tried with other addresses and even tried concatenating results, everything outputs the same issue.

  • Try debugging it using single step. Pay close attention to the registers and the top of the stack between each instruction. You should notice problems fairly quickly. – Erik Eidt Apr 03 '23 at 18:16
  • Why do you need to add 48? It's already the ASCII code of the number. You need to format that code as two digits in the output. – Barmar Apr 03 '23 at 18:18
  • Why isn't the desired result `input '53', 48`? Why doesn't the second number get converted? – Barmar Apr 03 '23 at 18:19
  • 1
    You are making too many calls where jumps would be advised. The stack must be left exactly like it was upon entering the code. Where is eax initialized? Please provide information about how `stoi` is called. – yacc Apr 03 '23 at 18:25
  • @Barmar: the input is a C string "5" which has two bytes, ASCII `'5'` and integer `0`. The OP is trying to convert that to an integer `5` I think? But doing it wrong and incorrectly expressing the integer value they want. `input: db '53', 0` would be a 3 byte string, C `"53"`, which makes no sense. `db 53, 0` would be the same 2 bytes as `db '5', 0`, just a different way of writing the first ASCII byte in the source. ('0' is 48, so '5' is 48+5 = 53). And their code isn't storing anything back to `input`, just overwriting the value in the AL register every time, after doing `'5' + '0'`. – Peter Cordes Apr 03 '23 at 18:38
  • 1
    See [NASM Assembly convert input to integer?](https://stackoverflow.com/q/19309749) for working 32-bit and 64-bit `atoi` functions. – Peter Cordes Apr 03 '23 at 18:40
  • I misunderstood, I thought you were looping through the string `input db '5', 0`, not that this was the definition of a variable named `input`. – Barmar Apr 03 '23 at 19:54
  • @ErikEidt can you explain how can I do that? – Pablo Cotí Apr 05 '23 at 21:29
  • Yes. The program has state. Some state is (usually) constant, like the program code itself. You don't really have to inspect that. But other state is variable, and you need to verify this variable program state, before each instruction runs, to make sure the prior instruction did the right thing. Common locations for state are the CPU registers and the stack. For the stack, you need to verify that pushes & pops are dynamically balanced b/c if you push more than pop the stack becomes unusable for others... – Erik Eidt Apr 05 '23 at 21:48
  • If you misunderstand what's at the top of the stack, you won't get the value you want on `pop`. So, one way to debug is, at each instruction boundary, verify that what you think is on the stack actually is. You would be able to find problems single stepping just a few instructions with that code. Maybe you wouldn't immediately finds solutions, but the problems should raise questions in your mind about how the various instructions work. You should be able to observe that `call` pushes a return address onto the stack — that's significant. – Erik Eidt Apr 05 '23 at 21:53

1 Answers1

1

You are using call instructions on several occasions. These are all supposed to become jumps of some kind!

The very first call stlEnd needs to be je stlEnd.
The last call stoiLoop needs to be jmp stoiLoop.
And the call stlContinue you can just remove.

stlEnd:
 mov eax, ebx

On this 1-character exercise this mov eax, ebx will destroy the resulting integer!
Your code is not converting a string to an integer. You are not accumulating any intermediate results from processing a current character. The only operation I see is a redundant addition to the ASCII code of a digit.

Trying to make sense of what you are aiming at, the next lines would be perfectly equivalent:

input db '5', 0
input db 53, 0

But do notice that there are no (single) quotes around 53.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76