0

I'm trying to figure out how to take a null-terminated normal IP address as a string and convert it to a 32-bit integer. In this example, my string is located at address ES:DI+Qapktdat. Qapktdat is a member of a struct defined as a string stored at ES:DI.

I have no problem reading from or writing to strings in the struct, but I have a problem with calculating the IP.

For example, If I use the string "192.168.7.2" then EDX should equal Hex value C0A80702 but I'm getting nothing close to it.

What could I be doing wrong?

ipconvmath:
  mov BX,Qapktdat-1 ;BX=data pointer. Set it to beginning of data -1
  mov CX,11h ;Look for null within the first 17 bytes of data
  ipend:
    inc BX
    mov AL,[ES:DI+BX]
    cmp AL,0
    je ipok
  loop ipend
  mov DX,-1 ;cant find null char so exit
  ret
  ipok:
  mov BP,10   ;BP = multiplier of multiplier
  xor EDX,EDX ;EDX = eventual IP address
  ;We scan IP address starting at LAST digit
  nextipseg:
    mov CX,1  ;CX= immediate multiplier
    xor DL,DL ;lower 8 bits of EDX = 0
    nxb:
      xor AX,AX
      dec BX
      mov AL,[ES:DI+BX]
      cmp AL,'.'
      je nodot
    ;Input isnt DOT so see if its number 0-9
    cmp AL,30h ;#0
    jb badipcnv
    cmp AL,39h ;#9
    ja badipcnv
    sub AL,30h
    mul CX ;multiply by 1, 10, or 100 depending on number position
    add DL,AL ;add it to our numeric IP
    mov AX,CX ;temporarily make AX=CX so multiply can work
    mul BP ;multiply the immediate multiplier by 10
    mov CX,AX
    cmp BX,Qapktdat ;see if were at beginning of data
    jne nxb
    ;we are so skip beginning
    nodot:
    rol EDX,8 ;shift existing contents over by 1 byte
  cmp BX,Qapktdat ;see if were at beginning 
  jne nextipseg
  ;here we are at beginning so were done
  ;EDX = ip address converted
  ret

  ;Reach here if a character is not 0-9 or a dot
  badipcnv:
    mov AX,1
  ret
  • check how many times `rol` is executed, what happens when `BX == Qapktdat`? – Iłya Bursov May 19 '21 at 05:40
  • What *are* you getting, and what do you see in a debugger? "doesn't work" isn't a problem description. – Peter Cordes May 19 '21 at 05:40
  • Also, since you're assuming 32-bit registers, you can use other post-8086 features like `imul reg, reg, 10`. (And you can simplify string->int by using only 1 `imul` per digit, or none at all using LEA with 32-bit addressing modes like in [NASM Assembly convert input to integer?](https://stackoverflow.com/a/49548057) Keeping track of place value to multiply by 1, 10, or 100 is more work and slower. – Peter Cordes May 19 '21 at 05:41
  • 1
    Semi-related: on modern x86 with SSSE3 - [Fastest way to get IPv4 address from string](https://stackoverflow.com/q/31679341). (And yes, that would work in 16-bit mode; SSE encodings do work.) – Peter Cordes May 19 '21 at 05:43

0 Answers0