在汇编语言x86中将数字字符串转换为整数

4
我正在尝试将用户输入的数字字符串转换为整数。
例如,用户输入“1234”作为字符串,我希望将1234存储在DWORD变量中。
我正在使用lodsbstosb来获取单个字节。 我的问题是我无法正确地编写算法。以下是我的代码:
mov ecx, (SIZEOF num)-1
mov esi, OFFSET num
mov edi, OFFSET ints
cld

counter:
   lodsb
   sub al,48
   stosb
   loop counter

我知道ECX计数器会有一点偏差,因为它读取的是整个字符串而不仅仅是4个字节,所以实际上是9,因为该字符串有10个字节。
我试图使用10的幂来乘以各个字节,但我对汇编语言还很陌生,无法得到正确的语法。如果有人能帮助解决算法问题,那就太好了。谢谢!

使用C库 - Jerfov2
请看这里 https://dev59.com/unfZa4cB1Zd3GeqPW9oK#19312503 - BioGenX
1个回答

1
一个简单的实现可能是:

    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

当然有办法来改善它,比如避免使用imul
编辑:修正了ecx的值。

“loop”指令在大多数CPU上都很慢,建议使用“dec”/“jnz”,或者根据“sub al, 48”设置的标志进行分支(在加载非数字字符后停止)。您可以使用“lea edx,[rdx + rax]”进行添加而不影响标志。是的,由于您可以使用LEA进行移位和加法,因此可以使用2个LEA指令执行“edx = eax + edx * 10”。gcc为这样的循环生成良好的代码。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接