まず第一に、これに返信してくれた人に感謝したいと思います。あなたの助けは大歓迎です!
コマンド ライン パラメータとしてプログラムに渡された一連の浮動小数点数の標準偏差を計算しようとしています。まず、各パラメーター文字列を変数に格納しtemp
、次に を使用してそれらを浮動小数点数に解析しますsscanf()
。私の最初の問題は、最初の(そして最初に言うとき、私は自分のプログラムの名前の後のものについて話しているので、実際には2番目の)コマンドラインパラメーターが解析されないことです。数値の平均を計算するために使用するループでは、各パラメーターを浮動小数点数に解析した直後に出力しようとします。最初のものを除くすべてを常に出力します。最初のものは常に として出力され-nan
ます。また、変数を変更したことはありませんが、変数も同様にstd_dev
出力されます。-nan
これは私を困惑させます。私は何を間違っていますか?
コードは次のとおりです。
EXTERN printf
EXTERN sscanf
GLOBAL main
SEGMENT .data
form0: DB "The standard deviation is: %d", 10, 0
form1: DB "The standard deviation is: %f", 10, 0
fpform: DB "%f", 0
avg: DD 0.0
std_dev: DD 0.0
temp: DD 0.0
debugform: DB "temp=%f, std_dev=%f, avg=%f", 10, 0
SEGMENT .text
main:
push ebp ; compose stack frame
mov ebp, esp
push ebx
push ecx
mov ebx, [ebp + 8] ; ebx = # of params
mov ecx, [ebp + 12] ; ecx = ¶m_table
cmp ebx, dword 1 ; no params passed?
je .end_0 ; YES - print 0
; NO - compute and print std_dev
finit ; initialize fpu
fldz ; initialize fpu registers with 0's
fldz
fldz
fldz
fldz
fldz
fldz
fldz
call findStdDev ; find the standard deviation of the numbers passed as command line params
call debugPrint
pushad ; preserve all registers before making system call
fld dword [avg] ; load standard deviation into fpu
sub esp, 8 ; reserve space for a qword in the stack
fstp qword [esp] ; load the 64-bit representation of std_dev into stack
push form1 ; pass format string
call printf ; print out the standard deviation
add esp, 12
popad
jmp .end ;
pop ebp
ret
.end_0: ; if no parameters are passed, print std_dev = 0
push dword 0
push form0
call printf
add esp, 8
.end:
pop ecx
pop ebx
pop ebp ; restore used register and return from program
ret
;-----------------------------------------------------------------------------------
findStdDev: ; assumes ebx = # params, ecx = ¶m_table
push edi ; save used regs
push esi
xor esi, esi ; clear esi as a precaution
mov esi, dword 1 ; loop counter for loop to find average of numbers
.find_avg:
cmp esi, ebx ; esi == number of params?
je ._break ; YES - break
pushad ; preserve registers before calling a C function
push temp ; temp storage for string representation of input nums
push fpform ; format string
push dword [ecx + esi*4] ; current command line param
call sscanf ; parse string to f.p.
add esp, 12
popad
call debugPrint ; should leave the CPU and FPU registers how they were before the call
fld dword [temp] ; st0 = temp ; st1 = sum
faddp st1, st0 ; st0 = sum + temp
;call debugPrint ; should leave the CPU and FPU registers how they were before the call
inc esi ; move to next command line param
jmp .find_avg
._break:
mov [temp], ebx ; temp = num of params
sub [temp], dword 1
fld dword [temp] ; st0 = #params; st1 = sum of params
fdivp st1, st0 ; st0 = (sum of params)/(#params)
fstp dword [avg] ; set avg; clear st0
pop esi
pop edi
ret
;----------------------------------------------------------------------------------------
debugPrint:
pushfd
pushad
sub esp, 24
fld dword [avg]
fld dword [std_dev]
fld dword [temp]
fstp qword [esp]
fstp qword [esp+8]
fstp qword [esp+16]
push debugform
call printf
add esp, 28
popad
popfd
ret
再度、感謝します!
[編集: 標準偏差の実際の計算はまだ完了していません。私が持っているのは、平均を計算するループだけです。]