请班竹帮忙呀!小弟搞了一个星期了。

michaelwan 2003-09-15 08:44:30
小弟现在想写一个测试浮点运算是否正确的程序:而且小弟也有相应的汇编代码,但是现在我想在VC下来实现,但我不是很清楚,他的原理,我尝试着把汇编代码转换为VC代码,但是总是没有成功,请班竹帮忙呀。下面是我要转换的汇编代码。

CARRY_ERROR EQU 1
REG_BITS_ERROR EQU 2
FLAGS_ERROR EQU 3
BCD_ERROR EQU 4
MUL_DIV_ERROR EQU 5
JMP_ERROR EQU 6
MUL386_ERROR EQU 7
LOGIC1_ERROR EQU 8
LOGIC2_ERROR EQU 9
CMPS_ERROR EQU 10
IOS_ERROR EQU 11
STRS_ERROR EQU 12
MOVS_ERROR EQU 13
PUSHA_ERROR EQU 14
NUM_REG = 8 ; NUMBER OF REGISTERS IN THE NPX
NUM_BITS = 64 ; # of bits to test in the significant
NUM_EXP = 14 ; # of bits to test in the exponent



;*****************************************************************************
;_ChkFpuArith
; Test FPU Arithmetics
; Entry: None
; Exit: AX=1 if PASS , AX=0 if Fail
;*****************************************************************************
PUBLIC _ChkFpuArith
_ChkFpuArith PROC far
push ds
push es
push bx
push si
push di

mov ax,CPUGROUP
mov ds,ax
finit ; initialize the npx
cli ; disable intrerrupts. then load the
mov control_word,133fh ; ctrl word: no exceptions, no interrupts
fldcw control_word ; 64 bits, round even, infinity affine
mov reg_counter,num_reg ; for each register do:
t001:
fild ds:two ; initialize register
mov bit_counter,num_bits ; for each bit in the significand field:
t002:
call check_significand ; if carry bit not set, flag error
jc short t004 ; and return

fimul ds:two ; generate carry (register*2)
fisub ds:one ; move bit to the right (register-1)
dec bit_counter
jnz short t002 ; end for

fstp st(0) ; initialize register (store and pop)
fild ds:four ; integer load 4
mov bit_counter,num_exp ; for each bit in the exponent field do:
t003:
call check_exponent ; if exponent incorrect, return
jc short t004 ;
fmul st,st(0) ; squares the content of the stack top
fidiv ds:two ; divide by two, sets next bit in exponent
dec bit_counter
jnz short t003 ; end for

xor ax,ax ; zero expected condition bits.
call condition_bits ; if register <> positive & nonzero
t004:
jnz short t007 ; flag error and return

fchs ; generate a nan (sqrt(-number))
fsqrt
mov ah,045h ; set expected condition bits.
call condition_bits ; if register <> (nan or infinity)
jnz short t007 ; flag error and return

fstp st(0) ; store and pop. initialize register 0
fldz ; load +0.0 into stack 0
mov ah,040h ; set expected condition bits.
call condition_bits ; if register <> zero (+ or -)
jnz short t007 ; flag error and return

fsub ds:alarge ; make register negitive and nonzero
mov ah,001h ; set expected condition bits.
call condition_bits ; if register <> negitive and nonzero
jnz short t007 ; flag error and return

dec reg_counter ; endif
jz short t006 ;
jmp t001
t006:
call check_stack ; check each register for -large
jz short t008
t007:
mov ax,0
jmp @F
t008:
mov ax,1
@@:
sti
pop di
pop si
pop bx
pop es
pop ds
retf
_ChkFpuArith ENDP

...全文
29 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ckp 2003-09-16
  • 打赏
  • 举报
回复
如liangbch(宝宝) 所说使用内嵌汇编,只是要注意在调用内嵌汇编时,要注意寄存器与堆栈的现场保护。
_asm
{
mov eax,a
mov edx,b
add eax,edx //在c子程序中,总是使用eax作为返回值
}
michaelwan 2003-09-16
  • 打赏
  • 举报
回复
其实也不是很长呀,主要是第一个函数ChkFpuArith,后面的condition_bits PROC near;check_significand PROC near; check_exponent PROC near; check_stack PROC near;主要是它call的子函数啦。有那位搞过浮点指令的朋友帮帮忙吧。谢谢!
nbgyf 2003-09-15
  • 打赏
  • 举报
回复
哇噻,这么长,给钱嘛

呵呵

开个玩笑,找本汇编书看看,搞懂各个指令(注意你的汇编指令的版本如intel386等等)


Good Luck!
SlayerCarrier 2003-09-15
  • 打赏
  • 举报
回复
这么长?
liangbch 2003-09-15
  • 打赏
  • 举报
回复
最简单的办法,在VC内嵌汇编。
下面是一个例子
C program:
int add(int a,int b)
{
return a+b
}
使用汇编后的代码:
int add(int a,int b)
{
_asm
{
mov eax,a
mov edx,b
add eax,edx //在c子程序中,总是使用eax作为返回值
}
}

zhucde 2003-09-15
  • 打赏
  • 举报
回复
太长.
楼主去找本汇编的书看看吧,
了解各个指令的意思,
知道了这个程序的意思,
改写起来不会难吧
michaelwan 2003-09-15
  • 打赏
  • 举报
回复
接:


******************************************************************
condition_bits PROC near
ftst ; test stack top against 0.0, set condition bits
fstsw status_word ; store the status word
fwait ; wait for npx to finish
and status_word,4700h ; strip off all but the condition bits
cmp status_word,ax
ret
condition_bits ENDP


;****************************************************************8
; check_significand
;
check_significand PROC near
mov ax,ds
mov es,ax
fsave full_npx_state ; put the npx reg stack in memory
frstor full_npx_state ; don't let npx re-initialize
fwait
xor al,al ; clear out the temporary buffer
mov di,offset temp_buff
mov cx,8
rep stos es:temp_buff
mov temp_buff+7,80h ; set bit 63
xor ah,ah ; calculate position of other bit
mov al,bit_counter ; divide by the # of bits in a byte
dec ax
mov bl,8
div bl ; divide by the # of bits in a byte
mov bx,ax
xor ah,ah
mov si,ax ; add byte offset of significand byte
mov al,bh ; translate the bit # to an actual
mov bx,offset ds:bit_table ; bit position
xlat ds:bit_table
or byte ptr temp_buff[si],al ; set bit in the temp_buff
mov si,offset temp_buff
mov di,offset byte ptr full_npx_state+14
mov cx,8
repe cmps temp_buff,byte ptr es:full_npx_state ; compare the two
jz short chk_sig_ok
stc ; Set carry flag is 1
jmp @F
chk_sig_ok:
clc ; Set carry flag is 0
@@:
ret
check_significand ENDP


;*****************************************************************
; check_exponent
;
check_exponent PROC near
fsave full_npx_state ; put the npx reg stack in memory
frstor full_npx_state ; don't let npx re-initialize
fwait
mov si,22 ; save the exponent offset in the
mov al,num_exp ; index register. then calculate the
sub al,bit_counter ; corresponding bit position
mov bx,offset ds:bit_table ; load the address of the offset table
cmp al,8 ; if in next byte, then do:
jl short chk_ex_1

sub al,8
xlat ds:bit_table
mov ah,al
xor al,al
jmp short chk_ex_2
chk_ex_1:
xlat ds:bit_table
xor ah,ah
chk_ex_2:
or ax,04000h ; set non-fraction bit
fwait ; wait for npx to catch up
cmp full_npx_state[si],ax ; if exponent not equal, then
jz short chk_ex_3
stc
ret
chk_ex_3:
clc
ret
check_exponent ENDP


;***********************************************************
; check_stack
;
check_stack PROC near
mov ax,ds
mov es,ax
fsave full_npx_state ; get the register stack into the buffer
fwait
mov ax,8 ; eight registers to check
mov di,offset bptr full_npx_state+14
chk_stk_01:
mov si,offset ds:minus_large
mov cx,10 ; load a loop count for 10 bytes
rep cmps ds:minus_large,byte ptr es:full_npx_state
jnz short chk_stk_02
dec ax
jnz short chk_stk_01
chk_stk_02:
ret
check_stack ENDP

请高手相助呀,我主要想把ChkFpuArith 转化为VC代码呀。

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧