で
おかげで、それは私がいないずっと前に手は小数点ルーチンからのみ、基本的な命令を使用して/するためにいくつかの文字列を書いています。
私が手助けしている別のグループについては既にコメントされていますが、役に立つかもしれません。
"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).
ご自身でテキストに変換するか、利用可能な場合はCライブラリを使用する必要があります。 – Jester
浮動小数点結果を必要としない場合は、代わりに整数除算命令DIVとIDIVを使用することができます。整数はテキストに変換する方が簡単です。 –
@Jesterありがとう、Cライブラリは本当にオプションではありません、私はそれをテキストに変換しようとします。私の理解からそれはそれが聞こえるほど簡単ではない... – MarkwinVI