回 帖 发 新 帖 刷新版面

主题:[讨论]求助!汇编语言实现开根号运算

学校老师出的实验题目,想来想去实在做不出~只好请教这儿的高手。

 开根号的算法我找到很多,但是用汇编语言能实现吗?汇编语言中如何实现实数运算呢?

 希望好心人能够指点一二~ 小弟在此先谢过~![em10]

回复列表 (共4个回复)

沙发

用汇编当然可以实现,但你应当先学习浮点指令。

板凳

摘自 masm32v8 的 fpusqrt.asm
; #########################################################################
;
;                             FpuSqrt
;
;##########################################################################

  ; -----------------------------------------------------------------------
  ; This procedure was written by Raymond Filiatreault, December 2002
  ; Modified January 2004 to remove data section
  ; Modified March 2004 to avoid any potential data loss from the FPU
  ;
  ;                           sqrt(Src) -> Dest
  ;
  ; This FpuSqrt function extracts the square root of a number (Src)
  ; with the FPU and returns the result as an 80-bit REAL number at the
  ; specified destination (the FPU itself or a memory location), unless an
  ; invalid operation is reported by the FPU or the definition of the
  ; parameters (with uID) is invalid.
  ;
  ; The source can be an 80-bit REAL number from the FPU itself or from
  ; memory, an immediate DWORD value or one in memory, or one of the FPU
  ; constants.
  ;
  ; The source is not checked for validity. This is the programmer's
  ; responsibility.
  ;
  ; Only EAX is used to return error or success. All other CPU registers
  ; are preserved.
  ;
  ; IF a source is specified to be the FPU top data register, it would be
  ; removed from the FPU. It would be replaced by the result only if the
  ; FPU is specified as the destination.
  ;
  ; IF source data is only from memory
  ; AND the FPU is specified as the destination for the result,
  ;       the st7 data register must be free, otherwise the error code
  ;       is returned in EAX and the FPU remains unchanged.
  ;
  ; -----------------------------------------------------------------------

    .386
    .model flat, stdcall  ; 32 bit memory model
    option casemap :none  ; case sensitive

    include Fpu.inc

    .code

; #########################################################################

FpuSqrt proc public lpSrc:DWORD, lpDest:DWORD, uID:DWORD
        
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;
; Because a library is assembled before its functions are called, all
; references to external memory data must be qualified for the expected
; size of that data so that the proper code is generated.
;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

LOCAL content[108] :BYTE
LOCAL tempst       :TBYTE

      test  uID,SRC1_FPU      ;is Src taken from FPU?
      jz    @F                ;go check for potential overflow

;-------------------------------
;check if top register is empty
;-------------------------------

      fxam                    ;examine its content
      fstsw ax                ;store results in AX
      fwait                   ;for precaution
      sahf                    ;transfer result bits to CPU flag
      jnc   continue          ;not empty if Carry flag not set
      jpe   continue          ;not empty if Parity flag set
      jnz   continue          ;not empty if Zero flag not set
      jmp   srcerr1

   @@:
      test  uID,DEST_FPU      ;is destination FPU if no source from FPU
      jz    continue          ;no extra register will be required

3 楼

;---------------------
;check if st7 is empty
;---------------------

      fdecstp                 ;get the st7 register as the top register
      fxam                    ;examine its content
      fstsw ax                ;store results in AX
      fincstp                 ;restore to the top register
      fwait                   ;for precaution
      sahf                    ;transfer result bits to CPU flag
      jnc   srcerr1           ;not empty if Carry flag not set
      jpe   srcerr1           ;not empty if Parity flag set
      jnz   srcerr1           ;not empty if Zero flag not set

continue:
      fsave content

;----------------------------------------
;check source for Src and load it to FPU
;----------------------------------------

      test  uID,SRC1_FPU      ;is Src taken from FPU?
      jz    @F
      lea   eax,content
      fld   tbyte ptr[eax+28]
      jmp   dest0             ;go complete process
      
   @@:
      mov   eax,lpSrc
      test  uID,SRC1_REAL     ;is Src an 80-bit REAL in memory?
      jz    @F
      fld   tbyte ptr [eax]
      jmp   dest0             ;go complete process
   @@:
      test  uID,SRC1_DMEM     ;is Src a 32-bit integer in memory?
      jz    @F
      fild  dword ptr [eax]
      jmp   dest0             ;go complete process
   @@:
      test  uID,SRC1_DIMM     ;is Src an immediate 32-bit integer?
      jz    @F
      fild  lpSrc
      jmp   dest0             ;go complete process
   @@:
      test  uID,SRC1_CONST    ;is Src one of the FPU constants?
      jnz   @F                ;otherwise no correct flag for Src

srcerr:
      frstor content
srcerr1:
      xor   eax,eax
      ret

   @@:
      test  eax,FPU_PI
      jz    @F
      fldpi                   ;load pi (3.14159...) on FPU
      jmp   dest0             ;go complete process
   @@:
      test  eax,FPU_NAPIER
      jz    srcerr            ;no correct CONST flag for Src
      fld1
      fldl2e
      fsub  st,st(1)
      f2xm1
      fadd  st,st(1)
      fscale
      fstp  st(1)

dest0:
      fsqrt                   ;get the square root of the number

      fstsw ax                ;retrieve exception flags from FPU
      fwait
      shr   al,1              ;test for invalid operation
      jc    srcerr            ;clean-up and return error

      test  uID,DEST_FPU      ;check where result should be stored
      jnz   @F                ;leave result on FPU if so indicated
      mov   eax,lpDest
      fstp  tbyte ptr[eax]    ;store result at specified address
      jmp   restore
   @@:
      fstp  tempst            ;store it temporarily

restore:
      frstor  content         ;restore all previous FPU registers

      test  uID,SRC1_FPU      ;was Src taken from FPU
      jz    @F
      fstp  st                ;remove source

   @@:
      test  uID,DEST_FPU
      jz    @F                ;the new value has been stored in memory
                              ;none of the FPU data was modified

      fld   tempst            ;load the new value on the FPU
   @@:
      or    al,1              ;to insure EAX!=0
      ret
    
FpuSqrt endp

; #########################################################################

end

4 楼

真的非常感谢~~ 看来我还需要多多努力~~

谢谢楼上的两位~  3Q~~~

我来回复

您尚未登录,请登录后再回复。点此登录或注册