1

I'm programming an STM8S microcontroller using STVD IDE. It uses the COSMIC compiler.

I found that there is a veriable that is increased unexpectedly. When debugging I found that there is a line in the assembly code that causes this variable to increase its value. It's a function named c_lgadc. Sometimes this assembly line is called while there is no ADC related function is shown in the call stack.

I don't understand where this code comes from and what is this c_lgadc? I have no function in my C code named c_lgadc

Here is a screenshot of the disassembly. enter image description here

UPDATE:

  • I don't know what C code should I examine as the call stack is different every time this disassembly line is called.
  • I've noticed that when I step over or into in the debugger, it comes to the last line of a specific timer ISR.
  • I've also noticed that the line with the second breakpoint is the one that causes addition to my variable. The line with first breakpoint is called always 5 times then the line with second breakpoint is called once and so on.
  • I'd like to know how should I debug this further to prevent the unexpected addition to my variable.

UPDATE2:

I found the following in the map file:

c_lgadc 0000f39c defined in (C:\Users\xxxxxxxx\CXSTM8\Lib\libm0.sm8)lgadc.o section .text
                 used in Debug\stm8s_it.o

I'm not sure if this would help in clarifying the problem?

Salahuddin
  • 1,617
  • 3
  • 23
  • 37
  • Not familiar with your tools but it's probably a library function. Adds the content of A to a 32-bit variable. You might want to examine the map file to see where this symbol comes from. – tum_ May 07 '19 at 17:34

2 Answers2

2

I've noticed that when I step over or into in the debugger, it comes to the last line of a specific timer ISR.

So, this timer ISR increments a 4-byte integer variable, and this variable overlaps with your variable. How such overlapping occurs might be revealed by inspecting that ISR or the link map, or it may be that the index register X is not correctly set in the ISR.

Armali
  • 18,255
  • 14
  • 57
  • 171
1

The function c_lgadc looks like part of a runtime library. Suggested by context, it is probably an add carry flag function because it is between the compare and unsigned right shift functions.

The c_l and c_lg prefixes for these functions are probably some part of a scheme indicate the types of the operands or their result.

As to your question, adc occurs in the instruction set of several CPU architectures, namely the intel x86 and motorola 680x. It means:

  • If the carry flag (unsigned arithmetic overflow or shift through carrry flag) is zero, return the operand as the result.
  • If the carry flag is set, return the result as one added to the operand.
wallyk
  • 56,922
  • 16
  • 83
  • 148
  • Thanks for the explanation. I now know what `c_lgadc` is or can be. Could you please tell me how can I prevent it from increasing my variable unexpectedly? Or how can I know what part of my C code can cause this `c_lgadc` increase this variable? – Salahuddin May 07 '19 at 17:44
  • @Salahuddin: If you can run the code under a debugger, you could breakpoint in the function and then single step until it returns. But since you are using a disassembly, it is much more difficult. Probably there are lots of places where this function is called like multi-word extended arithmetic and *creative* boolean logic evaluation. You'd have to look at every reference to it and somehow determine (I don't know how) whether that call is a candidate suspect. – wallyk May 07 '19 at 17:57
  • I do run the code under an ST-LINK debugger. I defined a breakpoint to occur if the memory location (where my variable is saved) is modified. When running the code, a breakpoint occur but not in my C code. Therefore, I opened the disassembly window and there was the breakpoint. – Salahuddin May 08 '19 at 07:47
  • Specifically, JRNC = jump if carry not set. JRNE = jump if not equal (zero). – Lundin May 08 '19 at 09:04