Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Floating point arithmetic Operations on floating point numbers are performed in the Floating Point Unit (FPU). The FPU supports seven different data types: • floating point numbers represented in: o single precision (32 bits) o double precision (64 bits) o extended precision (80 bits) – internal format • integers of type word, dword a qword • packed BCD integers Assembly Language 9/ 1 Registers of the FPU 8 80-bit data registers R0 to R7 • they hold operands • are organised as a stack • instructions refer to them as st(0), st(1), ..., st(7), the index being relative to the top of the stack 79 0 R0 R1 R2 R3 the top of the stack R4 st(0) R5 st(1) R6 st(2) R7 st(3) register notations in instructions Assembly Language 9/ 2 Tag register • 16-bit register • contains 8 tags that determine the state of the value in each register R0 to R7: Tag Meaning 00 The register contains a valid number. 01 The register contains 0. The contents of the register is special: 10 11 • a denormalized number – has the smallest exponent (0 in the number representation) and a nonnormalized mantissa (the highest bit is 0) = a very small number that cannot be normalized • a non-normalized number (has a non-normalized mantissa) • ± infinite (the result of an operation is out of the range of the extended precision format) • NaN (not a number); the FPU produces NaN when you perform a zero division or take the square root of a negative number Register is empty. Assembly Language 9/ 3 Status register 15 14 13 12 11 10 9 8 7 C3 C2 C1 C0 6 5 4 3 2 1 0 exception flags (indicate the state of the result of the previous operation) Bit Meaning 0 An invalid operation – this occurs as the result of a programming error, e.g. pushing more than 8 items onto the stack, attempting to pop an item off an empty stack or taking the square root of a negative number. 1 Denormalized number – this occurs when you try to manipulate denormalized values. 2 Division by zero. 3 Overflow – this occurs when you attempt to store a value which is too large to fit into a destination operand (e.g. storing a large extended precision value into a single precision variable). 4 Underflow. 5 Precision – occurs whenever the FPU produces an imprecise result (e.g. 1/3). 6 Stack fault (C1 = 1 ... stack overflow, C1 = 0 ... stack underflow). 7 Interrupt Request – is set to 1 if any exception occurs. 15 The FPU is busy. Assembly Language 9/ 4 stack pointer (contains the number of the register being at the top of the stack) Condition code bits C0, C2 and C3 are set after comparison of two numbers. Control register 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Bits 0 to 5 mask exceptions 0 to 5 recorded in the status register: if a mask is 0 and the corresponding condition occurs, then the FPU immediately generates an interrupt if a mask is 1 (default setting) then the FPU records the exception in the status register but does not call an interrupt Specify the precision Bits (the number of 9&8 mantissa bits) during computation: Bits Rounding control 11&10 00 To nearest or even (default setting) 00 24 01 Round down 10 53 10 Round up 11 64 (default setting) 11 Truncate Assembly Language 9/ 5 The FPU instruction set Data movement instructions fld real32 / real64 / real80 / st(i) load fild int16 / int32 / int64 integer load fbld BCD BCD load – load the operand to st(0). The instructions convert 16, 32 and 64 bit operands to an 80 bit extended precision value. Operand: variable or register st(i) fst real32 / real64 / st(i) store fist int16 / int32 integer store – copy the value from register st(0) to the operand. When copying data to a 16, 32 or 64 bit variable, the 80 bit extended precision value on the top of stack is rounded to the smaller format as specified by the rounding control bits in the FPU control register. Assembly Language 9/ 6 fstp real32 / real64 / real80 / st(i) store and pop fistp int16 / int32 / int64 integer store and pop fbstp BCD BCD store and pop – pop the value off the top of stack when moving it to the destination location. A conversion from the internal 80 bit extended precision format to the desired format is performed. fxch st(i) exchange registers – exchanges the value on the top of stack with one of the other FPU registers. fxch exchanges the contents of registers st(0) a st(1) Instructions pushing a constant onto the stack Instruction Constant fldz 0 fld1 1 fldpi π fldl2t log2(10) fldl2e log2(e) fldlg2 log10(2) fldln2 loge(2) Assembly Language 9/ 7 Arithmetic instructions fadd real32 / real64 fiadd int16 / int32 – add the operand to st(0). fadd st(0), st(i) fadd st(i), st(0) – add the operands and store the result to the left operand. faddp st(i), st(0) – st(i) := st(i) + st(0) and pop st(0). fadd and faddp do the same as faddp st(1),st(0) Subtraction: fsub (destination := destination – source) fsub; st(1):=st(1)–st(0) and pop st(0) Reverse subtraction: fsubr (destination := source destination) fsubr; st(1):=st(0)–st(1) and pop st(0) Multiplication: fmul Division: fdiv Reverse division: fdivr Assembly Language 9/ 8 Instruction Operation on st(0) fchs st(0) := - st(0) fsqrt st(0) := st(0) fabs st(0) := |st(0)| fsin st(0) := sin(st(0)) fcos st(0) := cos(st(0)) fsin and fcos are from the extended instruction set. Comparison instructions fcom real32 / real64 / st(i) compare ficom int16 / int32 integer compare – compare the operand with register st(0) and set condition bits C0, C2 and C3 in the status register. fcomp real32 / real64 / st(i) compare and pop ficomp int16 / int32 integer compare and pop – compare the operand with register st(0), set bits C0, C2 and C3 in the status register and pop st(0). fcom and fcomp compare st(1) against st(0) Assembly Language 9/ 9 compare and pop twice fcompp – compare st(1) against st(0), set bits C0, C2 and C3 in the status register and pop both ST0 and ST1 off the stack. test stack top ftst – compare st(0) with 0. Condition code setting according to the comparison: C3 C2 C0 Condition 0 0 0 st(0) > operand 0 0 1 st(0) < operand 1 0 0 st(0) = operand 1 1 1 st(0) or operand undefined Assembly Language 9/ 10 Control instructions finit – initialize the FPU. fldcw memory – load the control register from a memory location. fstcw memory – store the control register to a memory location. fstsw memory/AX – store the status register to a memory location or to register AX. fstsw ax is from the extended instruction set. Assembly Language 9/ 11 Converting floating point expressions to assembly language The FPU uses reverse polish notation (RPN) for arithmetic calculations. RPN is a postfix notation, which places the operator after the operands, as opposed to standard infix notation, which places the operator between the operands. a+b → RPN: ab+ (a+b)*(c+d) → RPN: ab+cd+* first you have to push the operands onto the stack and then execute the arithmetic or comparison instruction. finit; st(0) st(1) st(2) fld a; a fld b; b fadd; a a+b fld c; c a+b fld d; d c c+d a+b fadd; a+b fmul; (a+b)*(c+d) Assembly Language 9/ 12 Programming modules Modules are logical parts of the program, which are edited and compiled separately and linked together. Two directives are used to share data and procedures between modules: PUBLIC – instructs the compiler to make the associated symbols available to other modules. Symbols: variables labels and procedures constants EXTRN – makes public symbols from other modules available in a given module. The type of these symbols must be specified in the EXTRN directive so that the compiler could generate correct machine codes when assembling a given module. The type of a constant is abs. The type of a procedure may be specified as proc – the compiler will set the type to near or far depending on the memory model. Assembly Language 9/ 13 Interaction between Turbo Assembler and Turbo Pascal The main program in pascal: program DemoModules; uses ExampleUnit; begin CallAsm; end. unit ExampleUnit; {The example unit defines procedure CallAsm and several pascal procedures that are called from an assembly language procedure.} interface procedure CallAsm; procedure PublicProc; {far since it is visible outside} implementation var A: word; procedure AsmProc; external; {$L ASMPROC.OBJ} procedure PublicProc; begin writeln('In PublicProc'); end; Assembly Language 9/ 14 {$F+} procedure FarProc; {far due to compiler directive $F+} begin writeln('In FarProc') end; {$F-} procedure NearProc; {near since it is local in this unit} begin writeln('In NearProc'); end; procedure CallAsm; begin writeln('In CallAsm'); A := 10; writeln('Value of A before AsmProc = ',A); AsmProc; writeln('Value of A after AsmProc = ',A); end; end. Assembly Language 9/ 15 AsmProc.asm – this module will be linked together with the pascal unit and main program. The stack segment need not be defined here, because the stack defined in the pascal main program will be used when calling procedures. The assembly language data and code segments will be combined with the corresponding pascal segments. .MODEL small .DATA EXTRN A:word .CODE EXTRN PublicProc: far; exported by the unit EXTRN FarProc: far; local but forced far EXTRN NearProc: near; local to unit PUBLIC AsmProc AsmProc PROC call PublicProc call FarProc call NearProc dec A ret AsmProc ENDP END Assembly Language 9/ 16