digging into my code - C - ASM study

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems that a lot of my questions could be answered if I understood how to dig through the generated ASM code and compare to my written C code.   Please suggest reading or other media to get me started on this path.

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's a list of assembler instructions in the back of every

datasheet adjacent to the register summary.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try writing -very- simple test programs (just a couple of lines in the main loop) and looking at the assembly listings.  You may want to declare any variables as 'volatile' because otherwise the compiler may recognize that your simple program isn't doing anything and optimize your code away completely.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try with different optimizing levels.

 

Low level make clumsy code but tent to follow your C code.

 

the special -Og level is made so the code is easier to follow.

 

  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:
There's a list of assembler instructions in the back of every datasheet adjacent to the register summary.

Surely for any task such as this you want to study the "AVR Instruction Set" document.  It used to be doc0856.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You may want to start by identifying your C compiler. I think they each have the ability to show the Asm they generate (possibly in several different ways) but how you achieve that differs between each. After that you can just start to write simple C program like a single PORT write or perhaps a uint16_t/uint8_t = uint8_t <op> uint8_t (op is */+-^&| ) and see what the compiler generates. As others have said you can read about the Asm mnemonics involved in the opcode manual.

Last Edited: Sun. Jan 13, 2019 - 01:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks guys.  I was wondering how to correlate the ASM code locations to the C code location.  It sounds like the experienced folks write small test code to simplify this.  Just the advice I was looking for.

 

A bit of topic

clawson wrote:

You may want to start by identifying your C compiler.

I am using Studio 6.2 with gcc tools and have not bothered to upgrade.  It it worth the effort to move to 7?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

  It it worth the effort to move to 7?

Yes

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For GCC you have several options, there's a per source (unlinked) disassembly, there's an ELF disassembly and there's the preassembled source if -save-temps is used. I favour the latter. I wrote utility to add souce annotation back to it....

 

https://spaces.microchip.com/gf/...

Last Edited: Sun. Jan 13, 2019 - 02:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

For GCC you have several options, there's a per source (unlinked) disassembly, there's an ELF disassembly and there's the preassembled source if -save-temps is used. I favour the latter. I wrote utility to add souce annotation back to it....

 

https://spaces.microchip.com/gf/...

IIRC a compiler option is necessary to get the asm annotated.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
IIRC a compiler option is necessary to get the asm annotated.
Yup, that would be -g.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

KirkCharles wrote:

It seems that a lot of my questions could be answered if I understood how to dig through the generated ASM code and compare to my written C code.

 

Would they?

 

Unless you are trying to squeeze every bit of performance out of a chip I see no merit in digging through a compilers output. Much better to...

 

1) Learn to read, and understand, the datasheet.

2) Learn to write good embedded C.

3) Buy a big (A2) pad of paper, some pencils, and an eraser.

4) Learn to design your code before you code a single line.

5) Learn to debug your code using nothing more than an LED.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
I see no merit
While I agree that it's probably premature if you think you need this simply to optimize size/speed the fact is there is some merit in that it's simply an interesting learning experience cheeky

 

(of course I'm a bit of a frustrated asm programming luddite so possibly have a biased view - even on Pentium I tend to debug in a mixed C+Asm view as it's clearer to me what's going on by looking at the Asm code - especially true when debugging heavily (compiler) optimized code and you can't "see" where stuff is lurking without seeing which machine register it is in - but this is probably simply a requirement for getting my Scout's "luddite" badge!)

 

OP did start out by saying:

It seems that a lot of my questions could be answered if I understood how to dig through the generated ASM

I do wonder exactly what "lot of questions" this might be. I can't help thinking that whatever the questions were there might be a better way that trying to wade through asm?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I first started programming AVR's, and being an old ASM programmer and a novice C programmer, I would often produce a listing file (non-gcc compiler) and look at the mixed C / assembly produced.

One of the first oddities I noticed was the use of subtracting -1 when I incremented a variable, I thought that odd, until I looked at the instruction set and "discovered" the AVR has no add immediate instruction,

but it does have a subtract immediate!  Then it made sense.   I also noticed the code generated for Do/While & While loops are similar, basically the same code, with a different entry point, and For loops are also similar as well. 

I have never done any assembler on an AVR, but its nice to be able to at least read it.  Doing so has improved my C coding over time.

 

Ok, back to the main discussion after that side trip.

Jim

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if I understood how to dig through the generated ASM code

 I dunno.  Being able to make "some" sense out of the Compiler-produced ASM code doesn't really require that you be an expert assembly language programmer.  In fact, it can be a step TOWARD learning the assembly language...

 

Here are some random thoughts and comments:

  1. I prefer the ASM code produced by running avr-objdump on the .elf file, rather than the code produced by the compiler, or produced from the .o files.  Though they all have their uses.  Dumping the final .elf will have appopriate absolute addresses, which might be important (as in a recent casewhere incorrect linker configuration led to bad binaries.)  The compiler produced ASM will have actual labels, but ... usually a lot of EXTRA labels as well, and not very usefully named.
  2. use "-g" when compiling so that the compiler generates the info for mapping asm back to C line numbers.  You can use the (new) "-Og" optimization setting to get object code that should be easier to understand, but part of learning to "dig through" is learning how to understand even obscurely optimized code.
  3. use "avr-objdump -SC foo.elf" for disassembly.  the C option does de-mangling of C++ symbols, which can be helpful for Arduino sketches.  AFAIK, there is no down-side to using -C on non-C++ code.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn't know the -C option existed, will give it a try.

 

I add -z which means "Do not skip blocks of zeroes

when disassembling" because once I spent an hour

or two trying to figure out why there were no NOPs

in my code.  They were there, but since the opcode

is 00 00, they were suppressed by avr-objdump.

 

Looks like any multiple of 4 consecutive NOPs are

completely suppressed and replaced by a line with

just "...".  A non-multiple-of-4 is replaced by "..."

followed by a single NOP instruction.  The "..." was

really hard to spot because several lines of source

are printed between it and the single NOP.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:
In fact, it can be a step TOWARD learning the assembly language...
Totally agree with this - whenever I have started to work with a new micro (a rare occurrence these days sad) then I fond one of the best ways to learn its Asm is simply to debug in the mixed C+Asm view with a copy of the opcode manual alongside and just read about each new instruction that the C compiler has used as I come to it. (C compilers have a habit of using the common instructions and ignoring the esoteric ones!). It's also worth single stepping the opcodes in the Asm view to see register/flag results if something in the opcode manual about the operation is not immediately clear.