【问题标题】:Converting a string of numbers into an integer in Assembly x86在Assembly x86中将一串数字转换为整数
【发布时间】:2017-03-19 19:05:38
【问题描述】:

我正在尝试将用户输入的数字字符串转换为整数。

例如,用户输入“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 的幂来乘以单个字节,但我对 Assembly 还很陌生,无法获得正确的语法。如果有人可以帮助算法,那就太好了。谢谢!

【问题讨论】:

标签: string assembly x86 type-conversion int


【解决方案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 值

【讨论】:

  • The loop instruction is slow on most CPUs;只需使用dec / jnz,或在sub al, 48 设置的标志上分支(在加载非数字字符后停止)。您可以使用 lea edx, [rdx + rax] 添加而不影响标志。是的,因为您可以使用 LEA 进行移位和添加,所以您可以使用 2 个 LEA 指令执行 edx = eax + edx*10。 gcc 为这样的循环编写了很好的代码。
猜你喜欢
  • 1970-01-01
  • 2017-09-16
  • 2010-09-18
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-28
相关资源
最近更新 更多