⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 math.doc

📁 一个C style Assembler的source code
💻 DOC
字号:
     A R B I T R A R Y   P R E C I S I O N   M A T H   R O U T I N E S(0) Overview   To facilitate development of mathematical software on 8051-family ofprocessors, a set of routines has been developed that allows arithmeticoperations to be performed on data objects of arbitrary precision, and onfloating point data objects.  These routines will operate only on objectslocated in the 8051 internal data memory.(1) Arbitrary Precision Routines   All the following routines use the following registers:   R0 ... points to the destination data object located in internal memory.   R1 ... points to the source data object, if there is one.   R2 ... indicates the size of the data objects being operated on.These are the routines.  In this list, the names "Src" and "Dest" are used toindicate the source and destination objects.ClearX:    "Dest = 0"CopyX:     "Dest = Src"CplX:      "Src = ~Src"RolX:      "rotate Src left through the carry, C"ShiftX:    "shift Src left, high bit goes into C"LessX:     "C = (Src < Dest)"ZeroX:     "C = (Src == 0)"IncX:      "Dest++"CarryX:    "Dest += C"DecX:      "Dest--"BorrowX:   "Dest -= C"AddX:      "Dest += Src, carry goes into C"SubbX:     "Dest -= (Src + C), borrow goes into C"SubtractX: "Dest -= Src, borrow goes into C";NegX:      "Dest = -Dest"Inc10X:    "Increment Src in BCD format"The BCD increment operation (Inc10X) would take a data object of value,                       03 05 06 06 09 09hfor instance, and "increment" it to                       03 05 06 07 00 00hAs an example of how these routines are used, if the following declarationshad been made:X equ 30  ;;; allocate 3 bytes at registers 30-32 for XY equ 33  ;;; allocate 3 bytes at registers 33-35 for Yand if X, and Y were initialized as follows:   mov X, #43h   mov (X + 1), #24h   mov (X + 2), #02h   ;;; X = 22443h;   mov Y, #24h   mov (Y + 1), #00h   mov (Y + 2), #20h   ;;; Y = 200024h;then the following sequence:   mov R0, #X   mov R1, #Y   mov R2, #3   call AddX   ;;; X += Y;will carry out the operation indicated in the command above, and the Xdata object will have the value 222467h in the following format:           register  30  31  32           contents  67h 24h 22hThe carry flag, C, will be cleared.(2) The Multiplication Routines   (A) MultiplyX   The MultiplyX routine is actually an "add-and-multiply" operation thatallows you to accumulate the products into a data object.   The operation performed is:                         Z += X*Y;The user defines the X data object by setting the variable ArgX to point tothe data object, and setting SizeX to indicate the size of the object pointedto by ArgX.  The same thing goes with Y, with respect to the variables ArgYand SizeY.  The data object, Z, is pointed to by ArgZ.   So, for example, if the following declarations were made:Cycles equ 30 ;;; allocate 2 bytes at 30-31Total  equ 32 ;;; allocate 4 bytes at 32-35Product equ 36 ;;; allocate 6 bytes at 36-41then the following will add the product of Cycles and Total into Product:                mov ArgX, #Cycles                mov SizeX, #2                mov ArgY, #Total                mov SizeY, #4                mov ArgZ, #Product                call MultiplyX     ;;; Product += Cycles*Total;   (B) MulByR1   This is a routine that allows you to multiply a data object ("Dest") bya single byte.  The following registers are used:      R0 ... Points to the "Dest"      R1 ... Points to the multiplier byte      R2 ... Indicates the size of Dest.A multiplication is performed, the result is placed in "Dest", and the carrybyte is placed in R3.  For instance, if the following declaration was madeX equ 30 ;;; allocate 3 bytes to Xwith the initialization:                mov X, #7dh                mov (X + 1), #24h                mov (X + 2), #35h ;;; X = 35247dh;then this operation:                mov R0, #X                mov R1, #10h                mov R2, #3                call MulByR1  ;;; X += 10h;will multiply "X" by 10 (hexadecimal), so that X now will have the value5247d0h, formatted as follows:               register 30  31  32               contents d0h 47h 52hand R3 will have the carry (3).(3) The Fixed Point Routines   (A) DivideX   DivideX will carry out an arbitrary precision division (up to 8 bytes).The operand and divisor should be loaded into the registers Op, and Divisor.After DivideX, the registers Quo, and Fract will contain the integer partand decimal part of the quotient.  The effect is to carry out the operation:                        "Quo.Fract = Op/Divisor"   (B) Sqrt64   Sqrt64 calculates the square root of an 8-byte data object located inregister W, and returns a 4-byte result in register Q:                         "Q = sqrt(W)"For instance, if the following initialization is carried out:                       mov W, #21h                      mov (W + 1), #43h                      mov (W + 2), #45h                      mov (W + 3), #23h                      mov (W + 4), #01h                      mov (W + 5), #00h                      mov (W + 6), #00h                      mov (W + 7), #00h  ;;; W = 123454321hthen, the operation                      call Sqrt64will load Q with the square root (which is 11111h):                   register  Q   Q+1  Q+2  Q+3                   contents 11h  11h  01h  00hif W had be interpreted as a fixed-point quantity (12345.4321h), thenthe square root would still be a valid result, when properly interpreted(namely Q = 111.11h).  So this operation (and DivideX) works just as wellwith fixed-point arithmetic.(4) Allocating Registers   The assembler that I normally use does not handle relative addressing.  Thatmeans that I have to allocate the registers defined above by hand each timeI include this library.  If your assembler does not have the ability to handlerelocatible segments, you will likewise have to do the mapping of registervariables by hand.  In the library provided, these registers have been mappedas follows:For MultiplyX: SizeX   equ 30h ;;; 1 byte               SizeY   equ 31h ;;; 1 byte               ArgX    equ 32h ;;; 1 byte               ArgY    equ 33h ;;; 1 byte               ArgZ    equ 34h ;;; 1 byteFor DivideX:   SizeX   equ 30h ;;; 1 byte               Op      equ 35h ;;; 8 bytes               Divisor equ 3dh ;;; 8 bytes               Quo     equ 45h ;;; 8 bytes               Fract   equ 4dh ;;; 8 bytes               Rem     equ 55h ;;; 8 bytesFor Sqrt64:    Q       equ 35h ;;; 8 bytes               D       equ 3dh ;;; 8 bytes               X       equ 45h ;;; 8 bytes               W       equ 4dh ;;; 8 bytes               Y       bit F0The overlapping segments for DivideX and Sqrt64 are no major problem since theseroutines are never executed concurrently in any of my applications.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -