We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello, why is the simple code below assembled wrong? The disassembly copies the same value from the same memory location 0x06 to tp(n). (MOV @R0,0x06)
Thanks for Help Christian Tauschek
MY WRITTEN CODE: unsigned char tp[20]; for (n = 19; n > 0 ; n--) { tp[n] = tp[n-1]; }
__________________________________________ WRONG DISASSEMBLY:
46: for (n = 19; n > 0 ; n--) { C:0x08CA 7F13 MOV R7,#0x13 47: tp[n] = tp[n-1]; C:0x08CC 7421 MOV A,#0x21 C:0x08CE 2F ADD A,R7 C:0x08CF F8 MOV R0,A C:0x08D0 E6 MOV A,@R0 C:0x08D1 FE MOV R6,A C:0x08D2 7422 MOV A,#tp(0x22) C:0x08D4 2F ADD A,R7 C:0x08D5 F8 MOV R0,A C:0x08D6 A606 MOV @R0,0x06 48: } C:0x08D8 DFF2 DJNZ R7,C:08CC __________________________________________
MY uVISION3: IDE-Version: µVision3 V3.80 Copyright (c) Keil Elektronik GmbH / Keil Software, Inc. 1995 - 2009
License Information: Christian Tauschek Tauschek LIC=----
Tool Version Numbers: Toolchain: PK51 Prof. Develpers Kit Version: 8.18 Toolchain Path: C:\Keil\C51\BIN\ C Compiler: C51.Exe V8.18 Assembler: A51.Exe V8.01 Linker/Locator: BL51.Exe V6.20 Librarian: LIB51.Exe V4.24 Hex Converter: OH51.Exe V2.6 CPU DLL: S8051.DLL V3.65 Dialog DLL: DP51.DLL V2.54
Thanks for your answers, but i still have the problem. I tried to shorten the code as much as possible. If you replace the function call "get_taste()" with the code within the get_taste-function-code then it works ok. But i don't understand why. There should be no difference. Christian Tauschek
unsigned char tp[2]; unsigned char n, r1; void timer1_isr(void) interrupt 3 using 1 { TL1 = 0xef; TH1 = 0xd8; // if i replace this call "get_taste()" with // the get_taste-code below, then it works ok get_taste(); } void get_taste(void) { tp[0x00] = 0x0a; tp[0x01] = 0x0b; n = 0x01; tp[n] = tp[n - 1]; // there is the MISTAKE // now i expect the value 0x0a in r1, but r1 // has the value 0x00 r1 = tp[n]; }
Note the use of "using 1" which selects a specific register bank.
But how would get_taste() know that you call it from an ISR that is "using 1"?
When you mix code using different register banks, then you can get these effects.
Memory location 6 is always at the same place, but the definition of R6 will change depending on the currently used register set (the "using" part).
void get_taste(void) { tp[0x00] = 0x0a; tp[0x01] = 0x0b; n = 0x01; tp[n] = tp[n - 1]; // there is the MISTAKE
No. That is only where the mistake caused elsewhere finally bites.
There is a pair of places where the mistake is: you call a function from an ISR qualified "using 1", but the called function itself is not qualified "using 1". That combination is a monstrously big NO-NO.
Hello all, thanks for answers. Now, without "using 1", it works fine. I caused the mistake.
Christian Tauschek
However, using significantly reduces the overhead in your ISR - so you should really know how to use it properly (even if it isn't needed in this particular case)
See http://www.keil.com/support/man/docs/c51/c51_le_regbankaccess.htm for details.
Also: http://www.keil.com/support/man/docs/c51/c51_le_regbankspec.htm and the linked knowledgebase articles.