C Calling convention?

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

Hello!

Can anyone point me to some docs about the calling convention AVR GCC uses? I want to mix C / Aseembly code, and don't know how to implement the calling convention.

What registers can be freely modified, without push-pop-ing them to the stack, where are the parameters stored, where is the return value stored, and (I presume the return address is the top of the stack)

Any help is appreciated,
axos88

axos88

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

http://www.nongnu.org/avr-libc/u...

theres lots of stuff there, look around. Will keep you busy for a while :)

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

Is there a tutorial about mixing C and A code in AVR Studio?

axos88

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

Have you read the manual? (your questions so far are answered there). In this case:

http://www.nongnu.org/avr-libc/u...

and specifically:

http://www.nongnu.org/avr-libc/u...

but stop to ask yourself exactly WHY you think you need to write some of it in Asm - is it REALLY that timing/space dependent that it requires hand crafted assembler?

If it is then it's much easier to do things in separate .S source files than it is to try and inline asm("")

And a neat trick to avoid worrying about ABIs and calling conventions is simply to pass things in globals and not as parameters

Cliff

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

There aren't C compiler in AVR Studio, so you must read documentation for external compiler used in it.

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

Good point from awit. What'll you'll be combining is C written for avr-gcc with Asm written for (GCC's own) avr-as. You cannot combine Atmel AVRASM2 style assembler with C (either GCC or Imagecraft) in the Studio environment. The main difference are the directives involved. There's a manual for avr-as in \winavr\doc\binutils

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

Sorry for the unclear details. I am using WinAVR, that is AVR-GCC indeed, and I am using separate .S files.

Now calling the function works okay, but I cannot get the debugger to run through the assembly code :|

I can use the disassembler, but there are no LABELs, and it's very hard to descipher.

I am using assembly because I am actually writing a set of library functions for a general purpose heap (malloc, free), and want to make it as small and as efficient as possible. Right now, while there are some issues with using it, it is less than 200 bytes long. I don't think if I had written it in C it would be this small.

axos88

Last Edited: Tue. Jan 22, 2008 - 05:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Now calling the function works okay, but I cannot get the debugger to run through the assembly code

I can use the disassembler, but there are no LABELs, and it's very hard to descipher.


Which is one of the many arguments for not using Asm until this is fixed (well "fixed" is the wrong word, it's not "broken", it's just not implemented)
Quote:
I am using assembly because I am actually writing a set of library functions for the heap (malloc, free), and want to make it as small and as efficient as possible. Right now, while there are some issues with using it, it is less than 200 bytes long. I don't think if I had written it in C it would be this small.

Odd way of going about things - I'd write it in C then look at the generated assembler and if I didn't think it was compiling "tight enough" I'd look at ways of optimising it - either a handful of (casts) or perhaps a rewrite/reordering of things. Only if I got real stuck (can't get below 210 bytes!) would I maybe take the compiler's generated assembler and hand optimise it into a .S file.

It'll be far quicker to sketch out the algorithm in C and have the compiler write a solution for you than it will to hand implement the same algorithm in Asm (with the debug limitation)

If this stuff does "stand alone" one thing you might consider is actually writing it in AVRASM2 and debugging that then porting the solution to avr-as for inclusion in the GCC project. Or you might consider building for stabs and using the GNU debugger (gdb).

Cliff

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

Can you point me to a good tutorial using gdb? I tried looking around, but everything is for x86 platform. I tried invoking "gdb heaptest.elf", but it says "Don't know how to run". If i try "target exec", it says "No executable file now"

EDIT:
Got around the no executable file now error, I had to give "target exec heaptest.elf", but the "Don't know how to run" hasn't disappeared.

axos88

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

Ah but the joy of gdb is that it's pretty common to all architectures - so Intel manuals will apply to AVR (and ARM and so on). It's the same commands to set breakpoints or dump memory or whatever.

It's true that gdb when used "gdb fred.stabs" or "gdb eric.elf" is going to debug a local image on the host system but it can also debug a remote target (for which the command is "target remote ip_addr:port_num". To connect to the AVR you can either run the Linux based simulator simulavr (and a recent thread said it defaults to TCP port 1212) so you'd "simulavr file_to_debug" and then "gdb" and at the prompt "target remote :1212" (where no ip_addr means "localhost"). Or you need an OCD server (not sure what it's called for AVR) which talks GDB on a TCP port on one side and to a JTAG/Dragon and on to the AVR on the other side. In this case ip_addr would be the IP of the machine where the OCD server is running (not necessarily this one) and port is the port it elects to be visible upon.

One nice thing about gdb is that there are various GUI shells you can run on top (to hide the command line) such as ddd or Eclipse. I've used ddd a lot and really like it (though this was for ARMs not AVRs in fact)

Cliff

This may help:

http://sourceware.org/gdb/curren...

Oh and a quick check of the WinAVR install reminds me that the OCD server for AVR is avraice.exe which is documented in /winavr/doc/avarice

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

Yeah, I presumed that it would be common, but still avr-gdb won't execute the elf file for some reason... Can you tell me how to debug the debugging problem? :)

axos88

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

But avr-gdb is a win32 .exe program it's neither an interface to real AVR (avarice) nor a simulation of an AVR (simulavr) so how could it "run" a .elf containing AVR code. All it can do is load the symbolic information then stand ready to match this against the actual AVr code running on a remote AVR (or simulation thereof). Hence the use of "target remote" to "point" to either a simulation engine or a real AVR (via an ICE)

I guess you've been spoiled by AVR Studio where it just happens to have a simulator (or an ICE interfacer) and a debugger all built into the single program.

The solution to this (splitting the workload between two programs) truly is gdb's "target remote" command which "glues" the operation of two things back together

Cliff

Oh and when you use "ta re" in gdb remember that it's not "run" but "continue" you want to use to start the AVR code running on the AVR target (simulated or real)

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

I don't have ICE, or any kind of hardware debuggers... Is it possible to link against the AVR Simulator?

axos88

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

Yes, run the simulator (simulavr), and then use the port number the simulator
is listening on (1212 by default) to connect to, i.e. in the "target remote"
command.

Btw., there's a well-proven malloc()/heap() implementation already in the
library. It's a bit larger indeed (and I think it might have a little
potential of being optimized), but then, it's known to work including in
corner cases (like the top of heap being address 0xffff), and does (IMHO)
pretty well in re-combining the free()ed fragments. Given that using
malloc() is something that only applies for larger controllers (with enough
free RAM so you could actually do dynamic memory in the first place), I
can't really follow you on the cumbersome way of implementing it in hard
to maintain assembly. But of course, that's your turn.

If you watch out, Dean Camera ("abcminiuser") recently posted another
dynamic memory package which can also perform garbage collection. You might
want to have a look at this.

Regarding GDB, please make sure to use -gstabs as your debugging format,
AVR-GDB doesn't understand DWARF-2, really.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

dl8dtl wrote:

Regarding GDB, please make sure to use -gstabs as your debugging format,
AVR-GDB doesn't understand DWARF-2, really.

Whoops ....
I didn't know that , i assumed "but then ... I have heard that assumptions is the mother of all FSCK'ups"

Nice to know.

Now i know why Ted R. exitting , was such a big loss :-(

/Bingo

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

Yes, teaching AVR-GDB to understand DWARF-2 was on his plate, just
before he left. (The existing stabs handling for AVR is also his work.)

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

If for some reason, someone decides to try DWARF2 with AVR GDB, and runs into a bug, it would be nice if any bugs could be reported to the GDB bug database so we know exactly what is wrong with DWARF2 support in AVR GDB.

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

Well yeah, I know many of you don't understand why I am doing this, well I agree that I am inventing the wheel, but that's a way to learning to combine C and assembly, and this is a good way to do that. Btw, I am using an atmega8515, with 8k of flash, but it has an external memory interface, which will give me 64k of RAM. I will have to write some long code along with it, so I wanna keep heap handling as low as possible. I think my code is working now, 224 bytes, but maybe that could be reduced to around 210... later...

I still have a problem linking in the assembly source files, my .data section is not reckognized. Even thoug h I am declaring my heap as
.data
HEAP: .byte HEAP_SIZE

it doesn't get "compiled" into the final hex file.
While doing it with simple assembly, it recognizes the 258 bytes of heap in the data section, but when mixing it with C code, nothing:

AVR Memory Usage
----------------
Device: atmega8515
Program: 478 bytes (5.8% Full)
(.text + .data + .bootloader)
Data: 4 bytes (0.8% Full) <---- !!!!!
(.data + .bss + .noinit)
Build succeeded with 0 Warnings...

Hmmm... Now as I think about it, even 4 bytes is too low, because I have an integer i, and a 5-element pointer array declared, but maybe they are stored in registers... Umm yeah, never mind...

Thanks for your comments
axos88

axos88

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

.data is for /initialized/ data, so you need initializers.

What you're looking for is .bss, and the .comm pseudo-op. Obviously,
it would be simpler if you allocated the heap within the C part of
your application, and then only use it (as an external symbol) in the
assembly part...

Eric Weddington wrote:

> so we know exactly what is wrong with DWARF2 support in AVR GDB

Simply: it's unimplemented. If you look into what Ted once wrote for
the stabs part to work with AVRs, you'll quickly see what I mean. That
starts with the missing offset 0x800000 when accessing data items.

For a start, someone would simply have to consider everything AVR-specific
that is already there, and see whether DWARF-2 adaptation is needed for it.

I don't think there's much point in writing a dozen of bug reports, it's
merely a feature request (but rather a single one then).

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

My C calling convention:
@#$%#$% !!!@~##$$$ &**(&&& :lol:

Sorry could not resist this...I have tried all day... :evil:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Interesting. Looks about the same as trying to understand the
average assembly program someone else wrote. ;-)

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

So you are suggesting to use the HEAP as an external object... That would be okay, but there is one more problem to this:
I also need to know the size of the heap during compile -time of the assembly part, because they are used as constants throughout the code. Is it possible to use that as an external thing too?
And I want to make the whole thing transparent to the C file, so that I only have to make a single define, the size of the heap, the rest could be done with some .h includes, but I don't really have an idea how.

Now I know that instead of .byte HEAP_SIZE I should've used .space HEAP_SIZE, but now the size of the heap gets allocated 3x, because I have 3 seaparate files for each function (init,malloc,free), and they all include the "def.h", which contains the
".data
HEAP: .space HEAP_SIZE
"
part...

I uploded my project here: http://www.mediafire.com/?7jnrkabtxil, unfortunately AVRFreaks upload thing doesn't want to accept it...

EDIT: HEAP_SIZE is passed on to the assemblies by command-line now, but it would be nice if there was a way around this, so that we could do this in the .C file somehow...

EDIT2: Instead of the HEAP: .space HEAP_SIZE I used .comm HEAP, HEAP_SIZE, now the space used is being reported correctly. pfew, that's done... Now... Is there a way to define an external symbol with the CPP? #define will not be included in the object file...

axos88

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

Okay, I have now done almost anything, my code kinda works okay, but I have to supply the HEAP_SIZE define on the command line which is kinda uncomfortable. I would like the HEAP_SIZE to be declared as an external symbol, that would get linked in only at the linking stage, and would extern it from the .c (more likely .h) file.
Is this possible?

I tried to use .global, .extern, but nothing seems to work...

Also I have no idea how to extern a symbol from gcc into the object file

axos88

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

All the globals in C are just that - global so they'll be visible to Asm (as long as it decalres them as .extern). It doesn't work automatically the other way round you have to specifically announce anything that must be externally visible as .global

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

But if it's a compile-time constant, a global symbol (which would refer
to a variable in RAM) doesn't make much sense. Instead, just use a
#define for it, and then include the header file that defines the size
into both, the asm and the C file. The preprocessor will simply replace
the define by its right-hand side (it only replaces text), so if this is
a numeric constant, it's applicable to both asm and C.

Within the header file, you can differentiate those parts that will become
visible to the assembler by checking the macro __ASSEMBLER__.

There's no need to announce a global symbol (e.g. something defined within
your C code) by an .extern pseudo-op, because the assembler will automatically
consider all unknown symbols it encounters as "externally undefined", and
leave the resolution to the linker.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

No actually asm does declare anything unknown as external, so there wasn't a problem there, my problem was using them in macros....

So now I have to make a choice:
1. I will have readable code, but will have to build the heap library from code, and use a common .h header to supply the HEAP_SIZE
2. Make a symbol for every macro used, for ex. -1 * HEAP_SIZE, and HEAP_SIZE+2, and stuff like that.

Anyways, the code is now fully functional, but the compiler emmits some warnings about implicitly declaring the in-built functions malloc and free.... What can I do about them?
I know they are just warnings, but still... How nice it is when you see *no* warnings during compiling? :D

EDIT: Oh one more thing... The assembler does not reckognize the .bss directive, someone suggested using... only .data, but that will make the compiler initialize the data, which is not needed. Am I missing something, I suppose instead of
.data
.comm HEAP, HEAP_SIZE
I should write
.bss
.comm HEAP, HEAP_SIZE
But it says unkown pseudo-op.

EDIT2: Got around that, using .section bss, but the data is still initialized... It does'n hurt me that it gets initialized, but what for? :)
It eats up a whole 1k of cycles or sthg like that :P
Yea, I know it's just 1ms @ 1 MHz, but still...

axos88

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

It's part of the C standard that .bss will always be initialised to 0 (this is why you can rely on all non-initialised globals starting with 0)

Cliff

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

Is there a section that would not get initialized?
(even tried .noinit, but it gets initialized... wierd)

axos88

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

Well a section YOU define definitely won't (but I'm surprised by .noinit - can you show the code that's actually initialising it in the context of the pre-amble?)

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

axos88 wrote:
Is there a section that would not get initialized?
(even tried .noinit, but it gets initialized... wierd)
Remember that spelling counts:
.noinit != noinit
.bss != bss
'Tis an issue I've encountered before. :-(

Iluvatar is the better part of Valar.

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

Yeah at first it was like this:

.section noinit
.comm HEAP, HEAP_SIZE

But at your suggestion I also tried with .noinit, but still the same

.section .noinit
.comm HEAP, HEAP_SIZE

axos88

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

axos88 wrote:
Yeah at first it was like this:

.section noinit
.comm HEAP, HEAP_SIZE

But at your suggestion I also tried with .noinit, but still the same

.section .noinit
.comm HEAP, HEAP_SIZE

Have you checked to see whether you are getting things like .noinit.1 and .noinit.2?

Iluvatar is the better part of Valar.

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

Quote:
Have you checked to see whether you are getting things like .noinit.1 and .noinit.2?

Uh no, but how do I do that?

Anyways, I noticed something odd. I am using my own makefile, and making a .a file from the output .o files

when I apply avr-size -t libheap.a, nothing is reported in the data section (0 bytes), even if I change it to .bss or .data.

However, If I link it to C code, and that is built using the AVR Studios makefile generator, it is reported.

axos88

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

axos88 wrote:
Quote:
Have you checked to see whether you are getting things like .noinit.1 and .noinit.2?

Uh no, but how do I do that?

A *.lss file reports sections.

Iluvatar is the better part of Valar.

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

So does the .map file

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

Hmmm... nope....

With a C tester compiled in I get:

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000001d4 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00000102 00800060 000001d4 00000250 2**4
ALLOC
2 .stab 00000378 00000000 00000000 00000248 2**2
CONTENTS, READONLY, DEBUGGING
3 .stabstr 0000005f 00000000 00000000 000005c0 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_aranges 00000020 00000000 00000000 0000061f 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_pubnames 0000001b 00000000 00000000 0000063f 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_info 000000b8 00000000 00000000 0000065a 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_abbrev 00000067 00000000 00000000 00000712 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_line 000000ae 00000000 00000000 00000779 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_frame 00000020 00000000 00000000 00000828 2**2
CONTENTS, READONLY, DEBUGGING

And I am using

//.data
.section noinit
.comm HEAP, HEAP_SIZE

To define HEAP

axos88

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

Just for the record, if you succeed in getting something located in .noinit it looks like:

fred.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000096  00000000  00000000  00000074  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000002  00800060  00000096  0000010a  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000002  00800062  00000098  0000010c  2**0
                  ALLOC
  3 .noinit       00000002  00800064  0000009a  0000010c  2**0
                  ALLOC

Where the data items in this were produced by the C:

int eric __attribute__ ((section (".noinit")));
int pickle = 42;
int aardvark;

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

BTW I then added a .S file to the project and put this in it:

.section .noinit
.comm eric, 2, 1

which commons the two copies of 'eric'. Note the '.' at the start of noinit there. Also note the third parm to .comm - the alignment - because the linker complained otherwise that the C had generated 1 byte alignment but, by default, the .S had generated 2 byte alignment.

Having done this the only change in the LSS was to the description of .noinit:

  3 .noinit       00000002  00800064  00000098  0000010c  2**0
                  CONTENTS, ALLOC, LOAD, DATA

Finally I removed the definition from the C and .noinit disappeared from the list of ELF sections in the .lss file - so it looks like you do have to define the thing in C

Cliff

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

Well now... That... Umm... sucks... Can we call this a bug? :D

Yet another issue... Is there a way to make an assembly routines way into the initialization part of the C code? Like were the stack is initialized? I'd really love to see my heap_init routine in there :)

axos88

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

BTW, when I created the noinit variable in the C file the assembler was:

.global	eric
	.section	.noinit,"aw",@nobits
	.type	eric, @object
	.size	eric, 2
eric:
	.skip 2,0

And if I now remove it from C and put that into the .S file I find I have two bytes reserved in .noinit

So THIS is the solution.

(it's perhaps no surprise that the C compiler can write better avr-as assembler than we can! Which is why I'd have done this all in C)

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

Well yeah, I rewrote yesterday just out of curiosity the functions in C, and the results were:

heap_init - optimezed perfectly, 22 bytes, as the assembly
free - +10 bytes, 92 instead of 82
malloc - +10 bytes also, 124 instead of 114

So that's 20 bytes, almost 10%

But.... Total writing and debugging time... around 5000% less :P It was a good way to learn how to make C and A live in symbiosis though.

axos88

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

clawson wrote:

and specifically:

http://www.nongnu.org/avr-libc/u...

Unfortunately this example hide the most importand things (calling conventions, parameter passing), because its only an interrupt function without parameters and return value.

But I wont to add 64 bit support, so I need 64 bit parameter passing.

I found, that inline assembling can not be used, because the upper 4 bytes are not supported by the inline assembler.
Furthermore the compiler add code beside the assembler code, which destroy the register.

Is there a more helpful and detailed description, of the AVR-GCC .s format available?

clawson wrote:

but stop to ask yourself exactly WHY you think you need to write some of it in Asm

Yes, its needed, because the today 64 bit support waste tons of Flash.

E.g. division:
Assembler: 130 byte
GCC: 3632 byte

I wont to use 64 bit math for an 8 digit frequency counter on the ATtiny2313.

Peter

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

Peter,

By "64 bit support" are you talking about true "doubles", that is IEE754 floating point numbers in 64 bits or just "long long"s - don't see why the C would be 28 times the size of the Asm in the integer case. But equally you can't have got a whole 64 bit FPLib into 130 bytes of Asm either - it can only have been one very specific operation I think?

Cliff

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

danni wrote:
Unfortunately this example hide the most importand things (calling conventions, parameter passing), because its only an interrupt function without parameters and return value.

I think this FAQ entry tells you what you need to know about parameter passing and return values:
http://www.nongnu.org/avr-libc/u...

Essentially:
Parameters are passed to a function packed to the nearest 16-bit boundary. For fixed-parameter functions, the parameters start in r25 and grow down to r8, with any overflow going on the stack.

So if you have a function that takes 2 parameters, both 64-bit,
- the left parameter will be passed in r25:r24:r23:r22:r21:r20:r19:r18
- the right parameter will be passed in r17:r16:r15:r14:r13:r12:r11:r10

64-bit return values are sent to the calling function in r25:r24:r23:r22:r21:r20:r19:r18.

All these parameters and return values are little-endian.

The right parameter happens to be passed in the call-saved register space, so to be safe, if you need to re-use any of those registers inside your assembly routine for temporary values, you'll probably need to push their initial values onto the stack and restore them before returning.

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

Cliff,

long longs are tremendously inefficient with the current version of WinAVR.

I assume it's because there are no AVR-optimized versions of the routines available in avr-libc.

For most 64-bit arithmetic, AVR-GCC seems to pump out code that is probably akin to the floating-point code it generates when you don't link in libm.a. For example, for a simple unsigned 64-bit addition, it ignores the availability of the carry bit, and "simulates" it with conditionals. Yes, you read that right.

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

Hello!
Sorry if it is offtopic.

About using avrasm2 with gcc:
I recently wrote converter for converting gcc (cc1.exe)
assembly output in form which can be compiled with avrasm2.
It is not well tested yet but it work.

In attached file "Visual Studio 6.0" project and compiled "exe".

Attachment(s): 

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

Quote:
converter for converting gcc (cc1.exe)
assembly output in form which can be compiled with avrasm2

I gotta ask - why? (isn't avr-as a perfectly good AVR assembler then?)

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

first: now I need add some "C" code to existing avrasm2 project.

second: avr-as don't support back .org so I can't place interrupt routines in modules where they used.

for example this code in "main.asm"

.cseg
.org	0
rjmp	start
.org	INT_VECTORS_SIZE
start:
mov ...
ldi ...
...

and

ADC_INT:	;ADC interrupt
.org	ADCCaddr
jmp	ADC_INT
.org	ADC_INT
push	r31
in	r31,sreg
push	r31
sei
push	r30
push	r29
....

in separate ADC module.

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

.org is essentially a "Don't do this, ever" for a relocatable
assembler. It's been almost pointless to use already back 20+
years ago, when I've been working with the Z80 under CP/M.

The only reason it does exist at all in Atmel's assembler is that
this assembler is an absolute one -- no linking at all.

For any system that uses relocatable objects plus a linker, it's
the linker that decides about the final locations things are being
placed to, so that's whom you gotta tell about your interrupt
vectors.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Quote:
I gotta ask - why?

And I gotta ask - why did you choose this two month old thread about C, one that you not only did not start, but hadn't previously posted in at all, to place information about assembler.

Regards,
Steve A.

The Board helps those that help themselves.

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

ptbnfns wrote:
Hello!
Sorry if it is offtopic.

About using avrasm2 with gcc:
I recently wrote converter for converting gcc (cc1.exe)
assembly output in form which can be compiled with avrasm2.
It is not well tested yet but it work.

In attached file "Visual Studio 6.0" project and compiled "exe".

What software license are you using to license the code? I did not see anything about this in the package.

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

Quote:

For any system that uses relocatable objects plus a linker, it's
the linker that decides about the final locations things are being
placed to, so that's whom you gotta tell about your interrupt
vectors.

I would not have used such a method if interrupt vectors can be changed in the running program.
If so, I would simply called "SetIntVec."
But I can't.
In my view be better if some feature is entirely in a single file, and I do not need to change something else (such as linker setup) to add for example a UART driver.
Only one "include" and it's work !

Quote:

And I gotta ask - why did you choose this two month old thread about C....

I was looking for a complete solution to the problem and discovered that the thread in google.

Quote:

What software license are you using to license the code? I did not see anything about this in the package.

Anyone can do everything he wants.
I know very little of these legal licensing issues.
What I should specify in the source?

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

Quote:
What I should specify in the source?

"Free BSD" if you want to be as "open" as possible:

http://www.freebsd.org/copyright...

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

Quote:
I was looking for a complete solution to the problem and discovered that the thread in google.

But why this thread over the thousands of others on this site? Couldn't you have found one that was actually relevant to your post? Or maybe even try something novel like starting your own thread?

Regards,
Steve A.

The Board helps those that help themselves.

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

First good rule: PUSH any registers that youR assembler code wants to use on to the stack and POP them off upon exit. That way you know you are screwing nobody up.

 

Then C argument passing convention is that a first argument is passed in R22,R23; second argument in R24,R25 and beyond that you'll have to Google it.

So passing one byte uses two registers, but you can pass two unrelated byte arguments in R22,R23 for example.

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

Paul you are resurrecting a 9YO thread.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

And you are wrong about the ABI anyway. I don't really understand the point in guessing (wrongly) at some answer that even goes on to say "Google the rest"?

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

clawson wrote:
And you are wrong about the ABI anyway.

Well, depends on your toolchain. ;)  But moot given the necromancer aspects today.

 

[edit] Oops -- I missed that this was a multi-page thread and no mention of toolchain on the second page.  Indeed the thread starts out specifying GCC.

 

 

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.

Last Edited: Fri. Feb 17, 2017 - 10:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
Paul you are resurrecting a 9YO thread.

He seems to be making a habit of that:

 

https://www.avrfreaks.net/comment...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...