1

所以我对汇编语言相当陌生,我对基础知识有相当扎实的掌握,但用户输入总是让我感到困惑。所以现在我有以下代码可以从用户那里接收一个数字:

mov eax, 3
mov ebx, 0
mov ecx, inStrBuf
mov edx, StrLen
int 80h

然后定义如下

SECTION .bss
inStrBuf:  times StrLen resb  ' ' 

Section .data
StrLen: equ 8 

在我把值放入ecx之后,值就是数字+2608。所以我一直在做的只是简单地减去2608并得到数字。现在,当我输入多个数字时,例如数字 46,当我转换为十进制时,我得到 669236。没有像以前那样仅减去 2608 的简单方法。

首先,2608 是怎么回事,有没有办法只接受像 654 这样的数字并将其放入寄存器(当然是十六进制值)。谢谢!

4

1 回答 1

2

我不知道2608是从哪里来的,更不用说669236了!总体思路是:

;zero out someplace to put result
top:
;get a digit/character
;make sure it represents a decimal digit
;(if not - go to done)
;subtract '0' to convert character to number
;multiply "result so far" by 10
;add in the new number
;go to top
done:

这是我平时用的...

section .bss
    inStrBuf resb StrLen ; 12+ is good...

section .text
    ...
    push inStrBuf ; pass parameter on stack
    call atoi
    add esp, 4 ; clean up stack
    mov [someplace], eax
    ...

;--------------------
atoi:
    push ebx

    mov edx, [esp + 8]  ; pointer to string
    xor ebx, ebx ; assume not negative

    cmp byte [edx], '-'
    jnz .notneg
    inc ebx ; indicate negative
    inc edx ; move past the '-'
.notneg:

    xor eax, eax        ; clear "result"
.top:
    movzx ecx, byte [edx]
    inc edx
    cmp ecx, byte '0'
    jb .done
    cmp ecx, byte '9'
    ja .done

    ; we have a valid character - multiply
    ; result-so-far by 10, subtract '0'
    ; from the character to convert it to
    ; a number, and add it to result.

    lea eax, [eax + eax * 4]
    lea eax, [eax * 2 + ecx - '0']

    jmp short .top
.done:
    test ebx, ebx
    jz .notminus
    neg eax
.notminus:
    pop ebx
    ret
;------------------------

这使用了两个s的“聪明”方法lea乘以十,减去'0',然后添加新的数字。它的缺点是不设置标志,所以我们不能检查溢出——它只是默默地翻滚。任何“无效”字符停止 - 适用于 xero、换行(sys_read 将在那里)...或“垃圾”。当它返回时,“无效”字符将在 ecx 中(只是 cl 很有趣),并且 edx 指向下一个字符。方便解析“192.168.1.1”左右。您可能更喜欢使用更直接的东西。:) C 库“atoi”或“scanf”工作......如果你想那样做......

真的很好奇那个2608是从哪里来的!

于 2012-12-04T09:03:45.120 回答