This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Unexpected value in R0

Hi, I'm back with more questions :)

I have a 4-element array of 4-byte bit field structures filling up my bit addressable memory. Those structures are manipulated a lot in my code. I have found that assigning a pointer to an array element and then working with it generates much less code than working with the element directly. In one piece of my code, I want to do a logical operation with a lot of 2-bit structure fields. A line that does that looks like this:

pointerToStruct->2bitField ^= pointerToStruct->2bitField << 1;

This is compiled into a lot of instructions, but the beginning looks like this:

MOV R0, 0x01
PUSH
MOV A, @R0
MOV R4, A

My program breaks at the last instruction with error 65: access violation at I:0xE7: no 'read' permission. When I look at my registers, R0 really contains 0xE7. The first instruction should have put 0x01 in R0. PUSH should not have affected it as far as I know. If I check &pointerToStruct in the watch windows, the address is really D:0x01, so this should be ok.

Any ideas about how 0xE7 ended up in my 0xE7? Is it possible that my stack overflows? If it tried to go beyond 0x7F, would it wrap around and start writing into register banks or what?

Parents
  • Ok, I think I've tracked down the potential problem. My pointer is bad because the parameters passed to the function are wrong. My function takes 5 parameters, all in 0-3 interval. The call

    func(0, 0, 2, 3, 1);
    


    is compiled to:

    MOV 0x4C, #0x03
    MOV 0x4D, #0x01
    MOV R3, #0x02
    CLR A
    MOV R5, A
    MOV R7, A
    LCALL func
    

    Obviously, the call is try to pass some of the parameters through registers. However, when the program enters the function, the registers no longer contain the intended data because the caller was using different register bank. The called function fetches a parameter from R7, for example, but it contains 0x3f instead of 0.

    Is there any way to fix this? Can I give the compiler some directives that will make it aware that it can't use register banks like that?

Reply
  • Ok, I think I've tracked down the potential problem. My pointer is bad because the parameters passed to the function are wrong. My function takes 5 parameters, all in 0-3 interval. The call

    func(0, 0, 2, 3, 1);
    


    is compiled to:

    MOV 0x4C, #0x03
    MOV 0x4D, #0x01
    MOV R3, #0x02
    CLR A
    MOV R5, A
    MOV R7, A
    LCALL func
    

    Obviously, the call is try to pass some of the parameters through registers. However, when the program enters the function, the registers no longer contain the intended data because the caller was using different register bank. The called function fetches a parameter from R7, for example, but it contains 0x3f instead of 0.

    Is there any way to fix this? Can I give the compiler some directives that will make it aware that it can't use register banks like that?

Children