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

📄 bbu_library.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 5 页
字号:
; This subroutine performs an unsigned 32 bit divide. Users are encouraged to
; use the BBU_U32Divide routine in the BBU_Math.s file in place of this one for
; all new code. This older routine may be eliminated in the future.
;
; PARAMETER PASSING:
;
;       INPUT - r0 contains the dividend - (destroyed!)
;       INPUT - r1 contains the divisor - (destroyed!)
;
;       OUTPUT - r0 will contain the result
;       OUTPUT - r1 will contain the remainder
;
BBU_U32Div      FUNCTION

        stmfd   sp!,    {r2-r7, lr}     ; Save r2-r7, & link reg on stack

        mov     r6,     r0              ; Copy dividend ro r6
        mov     r7,     r1              ; Copy divisor to r7
        mov     r0,     #0              ; Clear result
        mov     r1,     #0              ; Clear remainder
        mov     r5,     #32             ; load r5 with loop count
        mrs     r4,     CPSR            ; Get CPSR
        bic     r4,     r4, #0x20000000 ; Clear carry bit
;
;       Main division loop begins here
;
10      msr     CPSR_f, r4              ; write flags back
        adcs    r0,     r0,     r0      ; Shift C bit into result
        adcs    r6,     r6,     r6      ; Rotate r6 left 1 bit through C bit
        adcs    r1,     r1,     r1      ; Rotate data left, into remainder
        subs    r1,     r1,     r7      ; Subtract dividend
        blt     %F12                    ; Branch if negative
        mrs     r4,     CPSR                    ; Get CPSR
        orr     r4,     r4,     #0x20000000     ; Set carry bit
        b       %F14                            ; Check loop count

12      add     r1,     r1,     r7              ; Restore remainder
        mrs     r4,     CPSR                    ; Get CPSR
        bic     r4,     r4,     #0x20000000     ; Clear carry bit

14      subs    r5,     r5,     #1      ; decrement loop count
        bne     %B10                    ; Loop until done
;
;       Shift the last bit into the result and return to caller
;
        msr     CPSR_f, r4              ; write flags back
        adcs    r0,     r0,     r0      ; Shift C bit into result
        adcs    r6,     r6,     r6      ; Rotate r6 left 1 bit through C bit
        ldmfd   sp!,    {r2-r7, pc}     ; Restore r2-r7 and return to caller

        ENDFUNC
;
;*********************************************************************************
;
;       **************
;       *            * 
;       * BBU_getnum * Subroutine "BBU Get Number"
;       *            *
;       **************
;
;       Last Update: 27-Jun-2006
;
; This subroutine searches the BBU input buffer (BBU_ibuf) for a valid hex or
; decimal value. The values are unsigned.
;
;       The hex value can range from 0x0 to 0xFFFFFFFF
;       The decimal value can range 0 to 4294967295
;       Note: A leading decimal point for a decimal number is optional (legacy code)
;
; PARAMETER PASSING:
;
;       INPUT:  r0 = Address of the first digit of the number
;
;       OUTPUT: r0 = Address of next byte (following the number)
;               r1 = Number detected in binary format
;               r2 = Decoded number status
;                       bit 0 - 0=No error, 1=Syntax error
;                       bit 1 - 0=No error, 1= Number too big
;                       bit 2 - reserved - returned as 0
;                       bit 3 - reserved - returned as 0
;                       bit 4 - 0=Decimal input, 1=Hex input
;
BBU_getnum      FUNCTION

        stmfd   sp!,    {r3-r4, lr}     ; Save used registers, & link reg on stack
        mov     r1,     #0              ; Set returned number to zero for now
        mov     r2,     #0              ; Clear return code - No error
;
;       The first byte should be pointing to the first digit before this routine
;       is called.
;
        ldrb    r3,     [r0],   #1      ; Get the first byte
        cmp     r3,     #'0'            ; Is this byte a <zero>?
        beq     %F10                    ; Yes - check for "0X" (Hex number) input
;
;       If the byte is in the range 1-9, Assume a decimal number is being entered
;
        cmp     r3,     #'1'            ; Compare byte to ASCII '1'
        blt     %F30                    ; Syntax Error if .LT. ASCII 1
        cmp     r3,     #'9'            ; Compare byte to ASCII '9'
        bgt     %F30                    ; Syntax Error if .GT. ASCII 9
        sub     r0,     r0,     #1      ; In decimal range - reset pointer (back up 1 byte)
        b       %F20                    ; Decode as a decimal number
;
;       A <zero> was found - If the next byte is an "X", assume the user is
;       inputting a hex value. If not, check the byte preceding the zero to
;       see that it is either a space or the start of the input buffer.
;
10      ldrb    r3,     [r0],   #1      ; Get the next byte in the buffer
        cmp     r3,     #'X'            ; is this byte an "X"?
        beq     %F15                    ; Yes - assume it is a hex number
        sub     r0,     r0,     #2      ; No - back up two bytes (points to ASCII zero byte)
        b       %F20                    ; No - assume it's a decimal number
;
;       A "0X" (zero, X) sequence was found - try to decode the following
;       bytes as if a hex number being entered.
;
15      bic     r2,     r2,     #8      ; Indicate possible hex number found
        mov     r4,     #0              ; Zero out a byte counter
16      ldrb    r3,     [r0],   #1      ; Get next byte in the buffer
        cmp     r3,     #0              ; Is this a NULL byte?
        beq     %F35                    ; Yes - return to caller
        cmp     r3,     #','            ; Is this byte a comma?
        beq     %F35                    ; Yes - return to caller
        cmp     r3,     #' '            ; Is this byte a <space>?
        beq     %F35                    ; Yes - return to caller
        cmp     r3,     #'/'            ; Is this byte a <forward slash>?
        beq     %F35                    ; Yes - return to caller
        cmp     r3,     #'0'            ; Compare to ASCII <zero>
        blt     %F30                    ; Lower - Syntax error!
        cmp     r3,     #'F'            ; Compare to ASCII "F"
        bgt     %F30                    ; Higher - Syntax error!
;
;       ASCII value is between ASCII<zero> and ASCII<F>  but the code still
;       needs to weed out anything above ASCII<9> and below ASCII<A>
;
        cmp     r3,     #0x3A           ; If less than this value, byte is 0-9
        sublt   r3,     r3,     #'0'    ; subtract ASCII<zero> if byte is in the 0-9 range...
        blt     %F17                    ; ...and add to r1
        cmp     r3,     #0x40           ; If greater than this value, byte is A-F
        subgt   r3,     r3,     #0x37   ; Subtract 0x37 to make byte binary...
        bgt     %F17                    ; ...and add to r1
        b       %F30                    ; Otherwise - Syntax error!

17      mov     r1,     r1,     LSL #4  ; Shift r1 left one nibble
        orr     r1,     r1,     r3      ; Add in data in r3
        add     r4,     r4,     #1      ; Increment byte count
        cmp     r4,     #9              ; 9th digit?
        orreq   r2,     r2,     #2      ; Set "number too large" bit
        beq     %F36                    ; ...and exit
        b       %B16                    ; Size is OK - Get next byte
;
;       Code picks up here if a decimal number was detected.
;       Start looking for numeric (0-9) digits to follow
;
20      ldrb    r3,     [r0],   #1      ; Get the next byte
        cmp     r3,     #0              ; Is this a NULL byte?
        beq     %F35                    ; Yes - return to caller
        cmp     r3,     #' '            ; Is this a <space>?
        beq     %F35                    ; YES - return to caller
        cmp     r3,     #','            ; Is this byte a comma?
        beq     %F35                    ; Yes - return to caller
        cmp     r3,     #'/'            ; Is this byte a <forward slash>?
        beq     %F35                    ; Yes - return to caller
        cmp     r3,     #'0'            ; Compare to ASCII <zero>
        blt     %F30                    ; Lower - Syntax error!
        cmp     r3,     #'9'            ; Compare to ASCII "9"
        bgt     %F30                    ; Higher - Syntax error!
;
;       Valid Digit entered - add it to the value in r6
;
        ldr     r4,     =0x19999999     ; Number can't be higher than this...
        cmp     r1,     r4              ; ...before the multiply by 10
        orrgt   r2,     r2,     #2      ; Set "number too large" (to multiply by 10)
        bgt     %F36                    ; ...and exit
        mov     r4,     #10             ; If OK - Set up multiplier
        muls    r1,     r1,     r4      ; Multiply r6 by 10
        sub     r3,     r3,     #'0'    ; Turn byte into binary...
        adds    r1,     r1,     r3      ; ...and add it to r1
        orrcs   r2,     r2,     #2      ; Set "number too large" bit if carry is set
        bcs     %F36                    ; ...and exit
        b       %B20                    ; OK so far - Get another byte
;
;       Syntax error detected in numeric input
;
30      orr     r2,     r2,     #1      ; Set Syntax error bit
        mov     r1,     #0              ; Clear returned number
;
;       Subroutine return path
;
35      sub     r0,     r0,     #1      ; Point to next byte AFTER the number
36      ldmfd   sp!,    {r3-r4, pc}     ; Restore r2-r4, & return to caller
        ENDFUNC
;
;*********************************************************************************
;
;       **************
;       *            * 
;       * BBU_ENCODE * Encodes a 32 bit binary value into an decimal ASCII string
;       *            *       ***** Use only for BBU TIME command *****
;       ************** ***** Use BBU_UDecToAscii routine for all other cases! *****
;
;       Last Update: 3-Aug-1004
;
; PARAMETER PASSING:
;
;       INPUT - r0 contains number to encode (destroyed)
;               r1 contains address where output is to be written (updated)
;               r2 contains formatting information as follows: (preserved)
;                       bits 3:0 = number of digits (1->16)
;                       bits 5:4 = 0-> left pad with NULLs
;                                  1-> left pad with zeros
;                                  2-> left pad with spaces
;
;
;       OUTPUT - NONE
;
BBU_ENCODE      FUNCTION
        stmfd   sp!,    {r3, r4, r5, lr}; Save r3-r5, & link reg on stack
        mov     r3,     r1              ; Save a copy of the pointer
        and     r4,     r2,     #0xF    ; Number of digits in r4
        mov     r2,     r2,     LSR #4  ; Shift r2 right 4 bits
        and     r2,     r2,     #3      ; Save bits 1:0
        mov     r5,     #0              ; Zero out a work register
;
;       Get 1,000,000,000s digit
;
        ldr     r1,     =1000000000     ; Load divisor
        bl      BBU_U32Div              ; Perform unsigned 32 bit divide
        cmp     r4,     #10             ; Display 10 digits or more?
        blt     %F41                    ; No - don't output this digit
        bl      BBU_FMTDIG              ; Yes - Format output byte
;
;       Get 100,000,000s digit
;
41      mov     r0,     r1              ; Copy remainder to r0
        ldr     r1,     =100000000      ; Load divisor
        bl      BBU_U32Div              ; Perform unsigned 32 bit divide
        cmp     r4,     #9              ; Display 9 digits or more?
        blt     %F42                    ; No - don't output this digit
        bl      BBU_FMTDIG              ; Yes - Format output byte
;
;       Get 10,000,000s digit
;
42      mov     r0,     r1              ; Copy remainder to r0
        ldr     r1,     =10000000       ; Load divisor
        bl      BBU_U32Div              ; Perform unsigned 32 bit divide
        cmp     r4,     #8              ; Display 8 digits or more?
        blt     %F43                    ; No - don't output this digit

⌨️ 快捷键说明

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