问题
I am trying to write a program that will convert a number from ieee to TNS (big endian), and vice versa. I'm very new to ARM and assembly in general. I'm not getting an error, its just not working as intended and I'd appreciate it if anyone could look at it. Every line is commented, the sub routine actually in question here is the "unpack ieee" procedure, it is not working as intended and I cannot see why. EDIT: IEEE and TNS numbers have 3 parts, I am attempting to "grab" or seperate the 3 parts using the masks. The unpack procedure is using the masks to place each part into a seperate register so that I can manipulate each part in order to convert it. Currently I am trying to confirm that the unpack procedure works by calling it, and then printing the registers. The numbers are either not printing or printing incorrect results.end edit I have not written the conversion routines yet, but I have a psudocode algorithm I can post if you'd like. Just let me know if there is anything else you'd like to know. The code:
AREA Conversion, CODE
SWI_WriteC EQU &0 ;output character in r0
SWI_WriteL EQU &2 ;output String in r0
SWI_Exit EQU &11 ;finish program
ENTRY
ADR r0, STRING ;load string
SWI SWI_WriteL ;print string
LDR r1, IEEE ;load IEEE num into r0
BL Print ;print number
BL UnpackIEEE ;call UnpackIEEE subroutine
ADR r1, r4 ;
BL Print
SWI SWI_Exit ;finish
UnpackIEEE
LDR r1, SMASK ;load the sign bit mask into r1
LDR r2, EMASK ;load the exponent mask into r2
LDR r3, GMASK ;load the significand mask into r3
AND r4, r0, r1 ;apply sign mask to IEEE and save into r4
AND r5, r0, r2 ;apply exponent mask to IEEE and save into r5
AND r6, r0, r3 ;apply significand mask to IEEE and save into r6
MOV pc, r14 ;return
ConvToTNS
Print MOV r2,#8 ;count of nibbles = 8
LOOP MOV r0,r1,LSR #28 ;get top nibble
CMP r0, #9 ;hexanumber 0-9 or A-F
ADDGT r0,r0, #"A"-10 ;ASCII alphabetic
ADDLE r0,r0, #"0" ;ASCII numeric
SWI SWI_WriteC ;print character
MOV r1,r1,LSL #4 ;shift left one nibble
SUBS r2,r2, #1 ;decrement nibble count
BNE LOOP ;if more nibbles,loop back
MOV pc, r14 ;return
IEEE DCD 0x40280000 ;2.75 or 40,280,000
TNS DCD 0x28000101 ;2.75 or 28,000,101
SMASK DCD 0x80000000 ;Sign bit mask
EMASK DCD 0x7F800000 ;Exponent mask
GMASK DCD 0x007FFFFF ;Significand mask
STRING DCB "HI THERE",0
END
回答1:
I think I know understand what you are trying to achieve.
I wrote up a program that uses the decimal number 15.75.
This number is stored in IEEE754 format.
It is first converted to TNS format the converted number is printed to the console.
The number is then converted back to IEEE745 format.
The converted number is printed to the console then the program exits.
This program is written for ARM7.
Take a look at the code if it sounds like that is what you are trying to achieve:
ENTRY
LDR r0, IEEE ; Load IEEE formatted # into r0
BL ieeetotns ; Branch to IEEE to TNS conversion subroutine
BL Print ; Branch to print number to console
BL tnstoieee ; Branch to TNS to IEEE conversion subroutine
BL Print ; Branch to print number to console
SWI SWI_Exit ; Exit Program
; Load IEEE Masks into registers
ieeetotns LDR r1, SIGNMASK ; Load sign mask into r1
LDR r2, IEEEEXPMASK ; Load IEEE exponent mask into r2
LDR r3, IEEESIGMASK ; Load IEEE significand mask into r3
; Convert from IEEE to TNS
AND r4, r0, r1 ; unpack sign bit, store in R4
AND r5, r2, r0 ; initial unpack of exponent, store in r5
MOV r5, r5, LSR #23 ; shift exponent right 23 bits
ADD r5, r5, #129 ; add 129(10) to exponent to correct excess encoding for TNS
AND r6, r3, r0 ; initial unpack of significand, store in r6
ADD r6, r7, r6, LSL #8 ; shift significand left 8 bits, kill off LSB
ORR r0, r4, r5 ; pack sign and exponent
ORR r0, r0, r6 ; pack significand with sign and exponent,
; r0 now holds IEEE to TNS converted word
MOV PC, LR ; Return to main subroutine
; Load TNS Masks
tnstoieee LDR r1, SIGNMASK ; Load sign mask into r1
LDR r2, TNSSIGMASK ; Load TNS Significand mask into r2
LDR r3, TNSEXPMASK ; Load TNS Exponent mask into r3
; Convert back to IEEE
AND r4, r0, r1 ; unpack sign bit
AND r5, r2, r0 ; initial unpack of significand, store in r5
MOV r5, r5, LSR #8 ; Shift significand right 8 bits
AND r6, r3, r0 ; Initial unpack of exponent, store in r6
SUB r6, r6, #129 ; Subtract 129 to correct excess encoding
ADD r6, r7, r6, LSL #23 ; Shift exponent left 23 bits
; Pack the converted number into r0
ORR r0, r4, r5 ; Pack sign and significand
ORR r0, r0, r6 ; Pack exponent with sign and significand,
; r0 now holds TNS to IEEE converted word
MOV PC, LR ; Return to main subroutine
Print MOV r2, #8 ; Count of nibbles = 8
MOV r1, r0 ; Move number to r1
MOV r3, r0 ; Store converted number in r3 for later
LOOP MOV r0, r1, LSR #28 ; Get top nibble
CMP r0, #9 ; Hex number 0-9 or A-F?
ADDGT r0, r0, #"A"-10 ; ASCII A-F
ADDLE r0, r0, #"0" ; ASCII 0-9
SWI SWI_WriteC ; Print character to console
MOV r1, r1, LSL #4 ; Shift left one nibble
SUBS r2, r2, #1 ; Decrement nibble count
BNE LOOP ; If more nibbles loop again
MOV r0, #10 ; Load 10 into r0, ASCII code for carriage return
SWI SWI_WriteC ; Print carriage return to console
MOV r0, r3 ; Move converted number back to r0
MOV PC, LR ; Return to main subroutine
IEEE DCW 0x0000, 0x417C ; IEEE Representation of 15.75(10), 417C0000(16),
; 01000001011111000000000000000000(2)
TNS DCW 0x0103, 0x7C00 ; TNS Representation of 15.75(10), 7C000103(16),
; 01111100000000000000000100000011(2)
; This is not used in program, simply here for comparison of conversions
SIGNMASK DCW 0x0000, 0x8000 ; Mask for sign bit
IEEEEXPMASK DCW 0x0000, 0x7F80 ; Mask for IEEE Exponent
IEEESIGMASK DCW 0xFFFF, 0x007F ; Mask for IEEE Significand
TNSSIGMASK DCW 0xFE00, 0x7FFF ; Mask for TNS Significand
TNSEXPMASK DCW 0x01FF, 0x0000 ; Mask for TNS Exponent
END
来源:https://stackoverflow.com/questions/13792564/arm-number-conversion-program