Close

Odpověď na: Linux x Windows rozdíly v kompilaci?

Úvodní stránka Fórum Hardware Arduino Linux x Windows rozdíly v kompilaci? Odpověď na: Linux x Windows rozdíly v kompilaci?

#10480
Zbyšek Voda
Správce

Začal jsem to zkoumat a je to celkem zajímavý problém.

Zkusil jsem udělat úplně jednoduchou non-void funkci, která ale, stejně jako u vás, nic nevrací. Ta funkce vypadá takto:

#include <stdint.h>

uint8_t fce(){
    
}

int main(){
    uint8_t a = fce();
    
	return 0;
}

Použil jsem uint8_t, protože boolean je vlastně „převlečený“ typ uint_8 – viz:
typedef uint8_t boolean;

Když tento miniprogram proženu přes kompilátor avr-gcc a zadám přepínače pro výstup v assembleru, získám kód níže. Příkaz pro spuštění kompilace je takovýto (jsem na MacOS):
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-gcc -S main.c

	.file	"main.c"
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__tmp_reg__ = 0
__zero_reg__ = 1
	.text
.global	fce
	.type	fce, @function
fce:
	push r28
	push r29
	in r28,__SP_L__
	in r29,__SP_H__
/* prologue: function */
/* frame size = 0 */
/* stack size = 2 */
.L__stack_usage = 2
/* epilogue start */
	pop r29
	pop r28
	ret
	.size	fce, .-fce
.global	main
	.type	main, @function
main:
	push r28
	push r29
	push __zero_reg__
	in r28,__SP_L__
	in r29,__SP_H__
/* prologue: function */
/* frame size = 1 */
/* stack size = 3 */
.L__stack_usage = 3
	rcall fce
	std Y+1,r24
	ldi r24,0
	ldi r25,0
/* epilogue start */
	pop __tmp_reg__
	pop r29
	pop r28
	ret
	.size	main, .-main
	.ident	"GCC: (GNU) 4.9.2"

K pochopení toho, co se děje, stačí najít řádek std Y+1,r24. Toto je instrukce v assembleru (viz . Slouží k tomu, že se někam do paměti na adresu danou Y+1 (proměnná a v programu) uloží hodnota z registru r24. Když se ale na program podíváte, do tohoto registru se předtím nic neukládá, ani se nenuluje, takže je hodnota nedefinovaná.

Tento příklad je zjednodušený, v případě při kompilaci pro Arduino dojde k připojení několika dalších funkcí. Pro ilustraci je to ale myslím dobré 🙂

Podle mě tedy dojde k tomu, že při kompilaci na Linuxu se ještě přidá instrukce pro vynulování registru r24. Je to ale jenom teorie. Můžete vyzkoušet, docela by mě zajímalo, jestli ten assemblerový kód vypadá stejně 🙂