2017-03-11 3 views
0

私はいくつかの簡単な除算を含むアセンブリプログラム(intel 8086 masm32)を作成しています。そして、部門がフロートを生み出すまで、すべてが働いていました。アセンブリの出力REAL 4の値

浮動小数点数をeaxレジスタにロードすると、大量の数値が返されるだけです。

問題を解決しようとすると、私はFUPについて知り、リアル4を使ってフロートを保存しています。
私の質問は、どのようにWriteConsoleA WindowsAPIを使ってコンソールにfloat REAL 4の値を出力できますか? この状況では、浮動小数点数を扱う別の方法がありますか?運として予め

+2

ご自身でテキストに変換するか、利用可能な場合はCライブラリを使用する必要があります。 – Jester

+0

浮動小数点結果を必要としない場合は、代わりに整数除算命令DIVとIDIVを使用することができます。整数はテキストに変換する方が簡単です。 –

+0

@Jesterありがとう、Cライブラリは本当にオプションではありません、私はそれをテキストに変換しようとします。私の理解からそれはそれが聞こえるほど簡単ではない... – MarkwinVI

答えて

0

おかげで、それは私がいないずっと前に手は小数点ルーチンからのみ、基本的な命令を使用して/するためにいくつかの文字列を書いています。

私が手助けしている別のグループについては既にコメントされていますが、役に立つかもしれません。

"strlen" procはscasbなどでより速くなることがありますが、基本的には初心者のための教育援助ですが、ASMであればどんなタスクでも簡単に十分です人間の相互作用を伴う。おそらくwsprintf et.alより速いでしょう。彼らは1つのケース(10進数)しか扱っていないためです。

小数点以下の文字列を出力するだけの場合、整数部分を出力してから02Ehを出力し、小数部分を10^SignificantPlacesに掛けて、それもまた。

ああところで

楽しん= D:私は計算の精度のビットを必要とするが、最終的な結果は整数になってしまうの多くの部門の仕事のために、そして限り、値として私がARENで働いています私は結果が得られ、それからちょうどxxx、すべてが何であっても、トラックについていくまで、xxx、8、またはshl xxx、16のすべてをdivし、それ以外のものは便利です)

あなたの現在のプロジェクトに適していますが、しばしば役に立つ方法です。

.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). 
関連する問題