我應該解決這個問題,我應該使用CDECL 約定計算x (6) 數字的算術平均值:
C 中的函式如下所示:float average(const float *array, long N, float (*f)(float), long *error);
section .data
array dd 1.5,-100.0,30.0,1.0,-1.0,90.0
array_len dd 6
error dd -1
section .text
average:
push ebp
mov ebp, esp
; condition if array is empty
cmp [ebp 8], dword 0
je .array_zero
; condition if array_len is 0
cmp [ebp 12], dword 0
jle .count_zero
; condition if passed function is null
cmp [ebp 16], dword 0
je .function_zero
; preserving registers
push esi
push edi
mov esi, [ebp 8]
mov ecx, [ebp 12]
; define-ing Quiet NaN (used as a error return value)
QNAN EQU 0x7FFFFFFF
MASK_IS_NAN EQU 0000_0001_0000_0000b
; applying the user-defined function on the numbers
.loop:
push ecx
lodsd
push eax
call dword [ebp 16] ; the pointer to the function is at this address
add esp, 4
pop ecx
fxam
fstsw ax
and ax, 0100_0101_0000_0000b
cmp ax, MASK_IS_NAN
je .is_not_a_number
fstp dword [edi ecx*4 - 4] ; storing the number in edi register
loop .loop
; calculating the arithmetic average
mov ecx, [ebp 12]
fld dword [edi ecx*4 - 4]
dec ecx
.calc:
fld dword [edi ecx*4 - 4]
fadd
loop .calc
fild dword [ebp 12]
fdiv ; the result of the arithmetic average is as defined in CDECL in st0 FPU register
; setting error = 0 and exiting
mov [ebp 20], dword 0
jmp .exit
.is_not_a_number:
mov [ebp 20], dword 8
jmp .error
.array_zero:
cmp [ebp 12], dword 0
jle .array_count_zero
cmp [ebp 16], dword 0
je .array_function_zero
mov [ebp 20], dword 1
jmp .error
.count_zero:
cmp [ebp 8], dword 0
je .array_count_zero
cmp [ebp 16], dword 0
je .count_function_zero
mov [ebp 20], dword 2
jmp .error
.function_zero:
mov [ebp 20], dword 4
jmp .error
.array_count_zero:
cmp [ebp 16], dword 0
je .all_zero
mov [ebp 20], dword 3
jmp .error
.array_function_zero:
cmp [ebp 12], dword 0
jle .all_zero
mov [ebp 20], dword 5
jmp .error
.count_function_zero:
cmp [ebp 8], dword 0
je .all_zero
mov [ebp 20], dword 6
jmp .error
.all_zero:
mov [ebp 20], dword 7
jmp .error
.error:
push dword QNAN
fld dword [esp]
add esp,4
jmp .exit
.exit:
pop edi
pop esi
mov esp, ebp
pop ebp
ret
fn_example:
finit
fld dword [esp 4]
xor ecx,-1
xor edx,-1
xor eax,-1
ret
CMAIN:
push ebp
mov ebp,esp
sub esp,4
; un-mask FPU exceptions
fstcw [esp]
and [esp],word 1111_1111_1110_0000b
fldcw [esp]
push error
push fn_example
push dword [array_len]
push array
call average
add esp,16
mov esp,ebp
pop ebp
ret
我在檢查結果的托管服務器上遇到分段錯誤,但在我的本地設備上,它作業正常。
任何想法,為什么會導致段錯誤?
uj5u.com熱心網友回復:
因此,我發現 EDI 暫存器 ( fld dword [edi ecx*4 - 4]) 導致了段錯誤,因為它不是 malloc-ed。奇怪的是,在 VSCode 除錯器中它作業正常,但服務器端編譯器對此有問題。
我在代碼中添加的內容:
...
mov esi, [ebp 8]
mov ecx, [ebp 12]
; ADDED SNIPET
lea eax, [ecx*4]
push eax
EXTERN malloc
call malloc
add esp, 4
mov edi, eax
mov ecx, [ebp 12]
; ADDED SNIPPET
; define-ing Quiet NaN (used as a error return value)
QNAN EQU 0x7FFFFFFF
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/472523.html
上一篇:磁區函式錯誤(mips程式集)
