2012-12-04 3 views
0

저는 어셈블리 언어에 대해 매우 익숙하지 않습니다. 저는 기초에 관해 꽤 견고한 이해를 가지고 있지만 사용자 입력은 항상 저를 당황하게했습니다. 그래서 지금 내가 사용자로부터 한 자리를받을 수있는 다음과 같은 코드가 있습니다NASM의 다 자리 입력

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

내가 ECX의 값을 넣어 후

SECTION .bss 
inStrBuf: times StrLen resb ' ' 

Section .data 
StrLen: equ 8 

를 다음과 같이 정의가를, 값은이다 digit = 2608. 그래서 내가 해왔 던 것은 단순히 2608을 빼고 숫자를 얻는 것이다. 이제 제가 46 자리 숫자와 같은 숫자를 두 개 이상 넣을 때 저는 10 진수로 변환하면 669236이됩니다. 이전처럼 2608을 빼는 간단한 방법이 없습니다.

우선 2608이 무엇인지, 그리고 654와 같은 숫자를 받아들이고 그것을 레지스터에 넣는 방법이 있습니다 (물론 16 진수 값으로). 감사!

답변

0

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 
;------------------------ 

이 10를 곱 두 lea의의 "똑똑한"방법을 사용, 빼기 ' 0 '을 입력하고 새 번호를 추가하십시오. 플래그를 설정하지 않는다는 단점이 있으므로 오버플로를 확인할 수 없습니다. 그냥 자동으로 롤오버됩니다. "유효하지 않은"문자 정지는 xero, linefeed (sys_read가있을 것입니다) ... 또는 "garbage"에서 작동합니다. 그것이 돌아 오면 "유효하지 않은"문자가 ecx (그냥 cl이 흥미 롭습니다)에 edx는 다음 문자를 가리 킵니다. 파싱에 편리한 "192.168.1.1"정도. 좀 더 간단한 것을 사용하는 것을 선호 할 수 있습니다. :) C 라이브러리 "atoi"또는 "scanf"작동 ... 만약 그걸 원한다면 그건 ...

정말 궁금한 곳에서 2608이 왔어!

관련 문제