Hallo Forum,
habe angefangen mit inline Assembler zu arbeiten und stosse schon auf die ersten Probleme:
Code:
#include <inttypes.h>
uint16_t fadd(uint8_t op1, uint8_t op2)
{
uint16_t result;
// op1 in 16bit register laden
// op2 mit carry aufaddieren und Ergebnis zurück geben
asm volatile (
"lds %A0, %1" "\n\t"
"add %A0, %2" "\n\t"
"adc %B0, 0"
: "=&r" (result)
: "r" (op1), "r" (op2)
);
return result;
}
int main(void)
{
uint8_t op1 = 10;
uint8_t op2 = 250;
uint16_t result = 0;
result = fadd( op1, op2 );
return 0;
}
Nach meinem Verständnis der Tutorials zu inline asm, die ich durchgearbeitet habe, sollte das reichen, um die beiden 8bit Werte mit carry zu addieren und das Ergebnis in die Variable result zurück zu schreiben. Leider meldet mir der Compiler das:
Code:
rm -rf scratch.o scratch.elf dep/* scratch.hex scratch.eep scratch.lss scratch.map
Build succeeded with 0 Warnings...
avr-gcc.exe -mmcu=atmega168 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=18432000UL -Os -fsigned-char -MD -MP -MT scratch.o -MF dep/scratch.o.d -c ../scratch.c
avr-gcc.exe -mmcu=atmega168 -Wl,-Map=scratch.map scratch.o -o scratch.elf
scratch.o(.text+0x2): In function `fadd':
../scratch.c:7: undefined reference to `r24'
make: *** [scratch.elf] Error 1
Build failed with 1 errors and 0 warnings...
Der asm Code (.S File) sieht so aus:
Code:
.file "scratch.c"
.arch atmega168
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
.global __do_copy_data
.global __do_clear_bss
.section .debug_abbrev,"",@progbits
.Ldebug_abbrev0:
.section .debug_info,"",@progbits
.Ldebug_info0:
.section .debug_line,"",@progbits
.Ldebug_line0:
.text
.Ltext0:
.global fadd
.type fadd, @function
fadd:
.LFB2:
.LM1:
/* prologue: frame size=4 */
push r28
push r29
in r28,__SP_L__
in r29,__SP_H__
sbiw r28,4
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
/* prologue end (size=10) */
std Y+1,r24
std Y+2,r22
.LM2:
ldd r25,Y+1
ldd r24,Y+2
/* #APP */
lds r24, r25
add r24, r24
adc r25, 0
/* #NOAPP */
std Y+3,r24
std Y+4,r25
.LM3:
ldd r24,Y+3
ldd r25,Y+4
/* epilogue: frame size=4 */
adiw r28,4
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
pop r29
pop r28
ret
/* epilogue end (size=9) */
/* function fadd size 33 (14) */
.LFE2:
.size fadd, .-fadd
.global main
.type main, @function
main:
.LFB3:
.LM4:
/* prologue: frame size=4 */
ldi r28,lo8(__stack - 4)
ldi r29,hi8(__stack - 4)
out __SP_H__,r29
out __SP_L__,r28
/* prologue end (size=4) */
.LM5:
ldi r24,lo8(10)
std Y+1,r24
.LM6:
ldi r24,lo8(-6)
std Y+2,r24
.LM7:
std Y+3,__zero_reg__
std Y+4,__zero_reg__
.LM8:
ldd r22,Y+2
ldd r24,Y+1
call fadd
std Y+3,r24
std Y+4,r25
.LM9:
ldi r24,lo8(0)
ldi r25,hi8(0)
/* epilogue: frame size=4 */
jmp exit
/* epilogue end (size=2) */
/* function main size 20 (14) */
.LFE3:
.size main, .-main
.Letext0:
.section .debug_line
.long .LELT0-.LSLT0
.LSLT0:
.word 2
.long .LELTP0-.LASLTP0
.LASLTP0:
.byte 0x1
.byte 0x1
.byte 0xf6
.byte 0xf5
.byte 0xa
.byte 0x0
.byte 0x1
.byte 0x1
.byte 0x1
.byte 0x1
.byte 0x0
.byte 0x0
.byte 0x0
.byte 0x1
.ascii ".."
.byte 0
.ascii "C:/Programme/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr"
.ascii "/include"
.byte 0
.byte 0x0
.string "stdint.h"
.uleb128 0x2
.uleb128 0x0
.uleb128 0x0
.string "scratch.c"
.uleb128 0x1
.uleb128 0x0
.uleb128 0x0
.byte 0x0
.LELTP0:
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM1
.byte 0x4
.uleb128 0x2
.byte 0x17
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM2
.byte 0x17
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM3
.byte 0x1b
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM4
.byte 0x32
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM5
.byte 0x16
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM6
.byte 0x15
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM7
.byte 0x16
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM8
.byte 0x16
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .LM9
.byte 0x16
.byte 0x0
.uleb128 0x3
.byte 0x2
.word .Letext0
.byte 0x0
.uleb128 0x1
.byte 0x1
.LELT0:
.section .debug_info
.long 401
.word 2
.long .Ldebug_abbrev0
.byte 0x2
.uleb128 0x1
.long .Ldebug_line0
.word .Letext0
.word .Ltext0
.string "GNU C 3.4.3"
.byte 0x1
.string "../scratch.c"
.string "D:\\\\priv\\\\Tech\\\\atmel\\\\learning\\\\scratch\\\\default"
.uleb128 0x2
.string "signed char"
.byte 0x1
.byte 0x6
.uleb128 0x3
.string "uint8_t"
.byte 0x1
.byte 0x46
.long 126
.uleb128 0x2
.string "unsigned char"
.byte 0x1
.byte 0x8
.uleb128 0x2
.string "int"
.byte 0x2
.byte 0x5
.uleb128 0x3
.string "uint16_t"
.byte 0x1
.byte 0x6d
.long 166
.uleb128 0x2
.string "unsigned int"
.byte 0x2
.byte 0x7
.uleb128 0x2
.string "long int"
.byte 0x4
.byte 0x5
.uleb128 0x2
.string "long unsigned int"
.byte 0x4
.byte 0x7
.uleb128 0x2
.string "long long int"
.byte 0x8
.byte 0x5
.uleb128 0x2
.string "long long unsigned int"
.byte 0x8
.byte 0x7
.uleb128 0x4
.long 333
.byte 0x1
.string "fadd"
.byte 0x2
.byte 0x4
.byte 0x1
.long 150
.word .LFB2
.word .LFE2
.byte 0x6
.byte 0x6c
.byte 0x93
.uleb128 0x1
.byte 0x6d
.byte 0x93
.uleb128 0x1
.uleb128 0x5
.string "op1"
.byte 0x2
.byte 0x3
.long 111
.byte 0x2
.byte 0x91
.sleb128 1
.uleb128 0x5
.string "op2"
.byte 0x2
.byte 0x3
.long 111
.byte 0x2
.byte 0x91
.sleb128 2
.uleb128 0x6
.string "result"
.byte 0x2
.byte 0x5
.long 150
.byte 0x2
.byte 0x91
.sleb128 3
.byte 0x0
.uleb128 0x7
.byte 0x1
.string "main"
.byte 0x2
.byte 0x2c
.byte 0x1
.long 143
.word .LFB3
.word .LFE3
.byte 0x6
.byte 0x6c
.byte 0x93
.uleb128 0x1
.byte 0x6d
.byte 0x93
.uleb128 0x1
.uleb128 0x6
.string "op1"
.byte 0x2
.byte 0x2e
.long 111
.byte 0x2
.byte 0x91
.sleb128 1
.uleb128 0x6
.string "op2"
.byte 0x2
.byte 0x2f
.long 111
.byte 0x2
.byte 0x91
.sleb128 2
.uleb128 0x6
.string "result"
.byte 0x2
.byte 0x31
.long 150
.byte 0x2
.byte 0x91
.sleb128 3
.byte 0x0
.byte 0x0
.section .debug_abbrev
.uleb128 0x1
.uleb128 0x11
.byte 0x1
.uleb128 0x10
.uleb128 0x6
.uleb128 0x12
.uleb128 0x1
.uleb128 0x11
.uleb128 0x1
.uleb128 0x25
.uleb128 0x8
.uleb128 0x13
.uleb128 0xb
.uleb128 0x3
.uleb128 0x8
.uleb128 0x1b
.uleb128 0x8
.byte 0x0
.byte 0x0
.uleb128 0x2
.uleb128 0x24
.byte 0x0
.uleb128 0x3
.uleb128 0x8
.uleb128 0xb
.uleb128 0xb
.uleb128 0x3e
.uleb128 0xb
.byte 0x0
.byte 0x0
.uleb128 0x3
.uleb128 0x16
.byte 0x0
.uleb128 0x3
.uleb128 0x8
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0xb
.uleb128 0x49
.uleb128 0x13
.byte 0x0
.byte 0x0
.uleb128 0x4
.uleb128 0x2e
.byte 0x1
.uleb128 0x1
.uleb128 0x13
.uleb128 0x3f
.uleb128 0xc
.uleb128 0x3
.uleb128 0x8
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0xb
.uleb128 0x27
.uleb128 0xc
.uleb128 0x49
.uleb128 0x13
.uleb128 0x11
.uleb128 0x1
.uleb128 0x12
.uleb128 0x1
.uleb128 0x40
.uleb128 0xa
.byte 0x0
.byte 0x0
.uleb128 0x5
.uleb128 0x5
.byte 0x0
.uleb128 0x3
.uleb128 0x8
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0xb
.uleb128 0x49
.uleb128 0x13
.uleb128 0x2
.uleb128 0xa
.byte 0x0
.byte 0x0
.uleb128 0x6
.uleb128 0x34
.byte 0x0
.uleb128 0x3
.uleb128 0x8
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0xb
.uleb128 0x49
.uleb128 0x13
.uleb128 0x2
.uleb128 0xa
.byte 0x0
.byte 0x0
.uleb128 0x7
.uleb128 0x2e
.byte 0x1
.uleb128 0x3f
.uleb128 0xc
.uleb128 0x3
.uleb128 0x8
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0xb
.uleb128 0x27
.uleb128 0xc
.uleb128 0x49
.uleb128 0x13
.uleb128 0x11
.uleb128 0x1
.uleb128 0x12
.uleb128 0x1
.uleb128 0x40
.uleb128 0xa
.byte 0x0
.byte 0x0
.byte 0x0
.section .debug_pubnames,"",@progbits
.long 32
.word 2
.long .Ldebug_info0
.long 405
.long 258
.string "fadd"
.long 333
.string "main"
.long 0
.section .debug_aranges,"",@progbits
.long 16
.word 2
.long .Ldebug_info0
.byte 0x2
.byte 0x0
.word .Ltext0
.word .Letext0-.Ltext0
.word 0
.word 0
/* File "../scratch.c": code 53 = 0x0035 ( 28), prologues 14, epilogues 11 */
Der erzeugte Code zu fadd sieht für meine Begriffe etwas befremdlich aus, da r24 zu sich selbst addiert wird? Hat da jemand eine Idee wo der Fehler liegt?
Lesezeichen