📄 math.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 + -