2017-03-11 2 views
0

몇 가지 간단한 구분이 포함 된 어셈블리 프로그램 (인텔 8086 masm32)을 만들고 있습니다. 그리고 사업부가 부유물을 생산할 때까지 모든 것이 작동했습니다.어셈블리에서 출력 REAL 4 값

eax 레지스터에 부동 소수점을로드 할 때 방대한 수를 반환하기 때문에.

FUP에 대해 알아 낸 문제를 해결하고 REAL 4를 사용하여 플로트를 저장하면 작동합니다.
내 질문에 어떻게 OutputConsoleA WindowsAPI 사용하여 콘솔에 부동 REAL 4 값을 출력 할 수 있습니다? 아니면 이런 상황에서 수레를 다루는 다른 방법이 있을까요? 행운으로 사전

+2

사용자가 직접 텍스트로 변환하거나 사용 가능한 경우 C 라이브러리를 사용해야합니다. – Jester

+0

부동 소수점 결과가 필요하지 않은 경우 정수를 텍스트로 쉽게 변환 할 수 있으므로 정수 나누기 명령어 DIV 및 IDIV를 대신 사용할 수 있습니다. –

+0

@Jester 고마워요, C 라이브러리는 정말 옵션이 아니에요, 나는 그것을 텍스트로 변환하려고 노력할 것입니다. – MarkwinVI

답변

0

에서

감사는 내가 얼마 전에 손 소수점 루틴에서 기본적인 지침을 사용하여/일부 문자열을 쓴 것이다.

그들은 내가 돕고있는 다른 그룹에 대해 이미 주석 처리되었지만 유용하다고 생각할 수도 있습니다.

"strlen"proc은 scasb 등으로 더 빠를 수도 있지만 기본적으로 초보자를위한 교육용 도구이지만 ASM은 물론 모든 작업에 대해 충분히 빠름 인간 상호 작용을 포함한다. 아마도 wsprintf et.al보다 빠릅니다. 단 하나의 경우 (십진수) 만 처리하기 때문입니다.

이들은 정수로만 쓰여지므로 10 진수 문자열 만 출력하면 정수 부분을 02Eh 뒤에 출력하고 소수 부분을 10^SignificantPlaces로 곱하면됩니다. 그것도.

오 BTW

재밌게 = D : 제가 계산을위한 정밀 약간 필요하지만 최종 결과는 정수를 끝나게 많은 분할하는 작업에 대해 다음과 같은 긴 값으로 나는 때로 믿을 함께 일하고 있어요 너무 커서 xxx, 8 또는 shl xxx, 16을 다 쓰고 그 다음 div와 그 밖의 무엇이든 다른 것이 무엇이든지간에 xxx는 무엇이든간에 모든 것을 저장하고 트럭에 보관하십시오.)

가능하지 않음 현재 프로젝트에 적합하지만 종종 유용한 방법입니다.

.data? 
    decbuf db 32 dup(?) 

.code 

; DECIMAL to/from STRING routines 
;  Lambchops 2/2017 
;  (a boy from AUS) 


strlen proc saddr:DWORD ; 
; return length of string at saddr 
    mov eax,saddr 
    dec eax 
    @@: 
    inc eax 
    cmp byte ptr [eax], 0 
    jnz @B 
    sub eax,saddr 
    ret 
strlen endp 

mul10 proc val:DWORD,expo:DWORD 
; multiply val x10 expo times 
    push ebx 
    push ecx 

    mov eax,val 
    mov ecx,expo 
    test ecx,ecx 
    jz mul10out 

    @@: 
     lea ebx,[eax*2] 
     lea eax,[ebx+eax*8] ; x2 + x8 = x10 
    loop @B 

    mul10out: 
    pop ecx 
    pop ebx 
    ret 
mul10 endp 

isDecChar proc cchar:DWORD 
    ; is the low byte of cchar '0'->'9'? 
    ; zf=true 
    push eax 
    mov eax,cchar 
    mov ah,1 
    cmp al,'0' 
    jb @F 
    cmp al,'9' 
    ja @F 
     xor eax,eax 
    @@: 
    test eax,eax 
    pop eax 
    ret 
isDecChar endp 


getDecimal proc saddr:DWORD 
; get the integer value of the unsigned decimal string at address saddr 
; 
; ignores any char that is not a decimal digit ** including '.' ** 
;---------------------------------------------------------------------- 
LOCAL retval 
    pushad 

    ; zero return value 
    mov retval,0 

    ; get src address 
    mov esi,saddr 

    ; get string length 
    push esi 
    call strlen 

    ; zero length string? 
    test eax,eax 
    jz getdecout 

    ; add the length to the buffer address 
    add esi,eax 

    ; esi points to zero terminator so dec 
    dec esi 

    ; set loop counter to string length 
    mov ecx,eax 

    ; zero the column number 
    xor ebx,ebx 

    @@: 
    xor edx,edx 
    ; get char in dl 
    mov dl,[esi] 
    dec esi 

    ; is the char a decimal digit? 
    push edx 
    call isDecChar 
    ; skip anything else 
    jnz skipBadChar 

     ; char '0'=48 so subtract this to get that char's value 
     sub edx,48 

     ; multiply by 10^column number 
     push ebx 
     push edx 
     call mul10 

     ; add to return value 
     add retval,eax 

     ; inc the column number 
     inc ebx 

    skipBadChar: 
    loop @B 

    getdecout: 
    popad 
    mov eax,retval 
    ret 
getDecimal endp 

strDecimal proc daddr:DWORD,val:DWORD 
;-------------------------------------------------------- 
; write unsigned integer val as a decimal string at daddr 
;-------------------------------------------------------- 
    pushad 
    mov edi,OFFSET decbuf 
    mov ebx,10 
    mov eax,val 

    ; generate the string 
    ;(backwards in decbuf) 
    @@: 
    ; must clear edx before using div 
    xor edx,edx 

    ; "div" divides eax by the operand (here ebx=10) 
    ; and leaves the remainder in edx, so the remainder 
    ; becomes our next digit value, and we continue 
    ; until eax=0 
    div ebx 

    ; add '0' to the remainder to convert 
    ; it to an ASCII char 
    add dl,48 

    ; write the char to the buffer 
    mov [edi],dl 

    ; inc the buffer ptr 
    inc edi 

    ; finished? 
    test eax,eax 
    jnz @B 

    ;append a zero terminator 
    mov BYTE ptr[edi],0 

    ; reverse the string and copy to daddr 
    ; (you can work this out, surely ;) 
    push OFFSET decbuf 
    call strlen 

    mov ecx,eax 
    add eax,OFFSET decbuf 
    mov edi,daddr 
    @@: 
    dec eax 
    mov dl,[eax] 
    mov [edi],dl 
    inc edi 
    loop @B 
    mov BYTE ptr[edi],0 
    popad 
    ret 
strDecimal endp 

; Please Note: 
; 
; These routines have not been exhaustively tested under all 
; conditions but appeared to function correctly for the task 
; they were written for (punting smallish integers to and 
; from a bunch of EditText boxes).