尝试在基于ARM的程序集中将使用的寄存器和返回地址保存在堆栈上时出现数据中止错误

时间:2019-12-11 19:09:36

标签: assembly arm

instruction run before error data abort next instruction goes to invalid instruction

图像是从CCS中的调试器模式拍摄的。

此分配的问题陈述是:

  1. 在您的第一个版本程序中,您将计算16摄氏度温度值的四舍五入平均值,并将结果放入名为Celsius_Av的命名存储位置。

  2. 当平均版本正常工作时,您将开发并调用一个过程,该过程确定每个摄氏温度值的华氏温度值,并将华氏温度值放入名为FahrenheitTemps的数组中。该过程还将计算平均华氏温度,并将该平均温度返回到主线,该平均线会将其置于称为Fahrenheit_Av的内存位置。

我能够很好地完成第一部分,并尝试第二部分。这是我的代码,当我保存使用过的寄存器并返回堆栈时,似乎无法摆脱数据中断。

   .text
   .global _start
    _start:
    .equ    NUM, 8


                    LDR     R13,=STACK              @   Point at stack pointer to bottom of stack space
                    ADD     R13,R13,#0x100          @   Point stack pointer at top of stack
                    LDR     R0,=FAHRENHEIT_TEMPS    @   Load pointer to second array
                    LDR     R1,=FAHRENHEIT_AV       @   Load pointer to second array
                    MOV     R2,#NUM
                    STMFD   R13!,{R0-R2}            @   Push set of Parameters on stack
                    LDR     R0,=CELSIUS_TEMPS1      @   Load pointer to array
                    LDR     R1,=CELSIUS_AV          @   Load pointer to Celsius_AV array
                    MOV     R2,#NUM                 @   Initialize counter NUM=8


                    BL      CONVERSION              @   Call Procedure to do work
    CONVERSION:     STMFD   R13!, {R5-R8,R14}       @   Save used registers and Return address on stack
    NEXT2:          LDRB    R6,[R0],#1              @   Get Celsius_Temps byte
                    MUL     R8,R6,#9                @   Multiply first Celsius_Temps by 9
                    MOV     R5,#0                   @   Counter
    LOOP: 
                    ADD     R5,R5,#1                @   Counter plus 1
                    SUB     R8,#5                   @   Subtract 5 from R8
                    CMP     R8,#0                   @   Compare R8 to zero
                    BPL     LOOP                    @   Go to LOOP if positive or zero
                    MOV     R8,R5                   @   Division by 5 into R8
                    ADD     R8,#32                  @   Add to 32 to complete conversion 
                    STR     R8,[R0],#1              @   Store in (FAHRENHEIT_TEMPS) array
                    MOV     R2,#16                  @   Set counter to 16
                    SUBS    R2,R2,#1                @   Decrement counter
                    BNE     NEXT2                   @   Repeat until 16 elements converted
                    ADD     R13,R13,#12             @   Add 12 to point R13 at parameters pushed on stack
                    LDMFD   R13!, {R0-R2}           @   Pop pushed values off stack into registers R0-R2
    NEXT3:          LDRB    R6,[R0],#1              @   Get Fahrenheit_Temps byte, increment pointer
                    LDRB    R7,[R0],#1              @   Get Next Fahrenheit_Temps byte, increment pointer
                    ADD     R5,R7,R6                @   Add sum in R5
                    ADD     R8,R8,R5                @   Add sum in R8
                    SUBS    R2,R2,#1                @   Decrement element counter
                    BNE     NEXT3                   @   Repeat loop until 16 elements added
                    MOVS    R8,R8,LSR#4             @   Divide by 16 LSB to carry
                    ADC     R8,R8,#0                @   Add contents of carry flag to sum
                                                    @   in R8 to round result up if carry=1
                    STRB    R8,[R1]                 @   Copy result byte to FAHRENHEIT_AV array
                    SUB     R13,R13,#32             @   Add 32 to get back to original position
                    LDMFD   R13!, {R6-R8,R14}       @   Pop pushed values off stack into registers 
                    ADD     R13,R13,#20             @   Add 20 to R13 to put stack pointer back at 
                                                    @   original position (Balance Stack)
                    MOV     PC,R14                  @   Return to mainline program

    .data
    CELSIUS_TEMPS1:     .byte   0x00,0x03,0x06,0x09,0x0C,0x0F,0X12,0X15,0X18,0X1B,0X1E,0X21,0X24,0X27,0X2A,0X2D
    CELSIUS_AV:         .byte   0X00
    FAHRENHEIT_TEMPS:   .byte   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    FAHRENHEIT_AV:      .byte   0x00    

    STACK:              .rept   256                 @   Reserve 256 bytes for stack and init with 0x00
                        .byte   0x00    
                        .endr   


  .end

我已经对代码进行了重新处理,以使该划分有效,但是除非我注释掉Pushing to R13,即堆栈,否则无法调试程序。我不能从堆栈中推送或弹出吗?当我要存储到数组时,它也会使我在调试器中中止数据。 我知道数组可以工作,并且可以完成分配第一部分中应该做的事情。我只是不知道如何无法将寄存器和数组放在堆栈上?

0 个答案:

没有答案