Close

Initial test: How Assembly, C, Arduino code are working?

A project log for Minimalist A-go-go

A project inside Attiny. I will not step out for larger one till I complete it.

kodera2tkodera2t 03/13/2016 at 07:260 Comments

I've wanted to make "LED blink" by Assembly, C, and Arduino IDE and compare them, and see how they are working. Here is a result.

Firstly I made a simple Assembly code of LED blinking connecting PB0 and PB1 with LEDs in Atmel Studio. As a initial test, I did not use timer and its internal interrupt. Delay function is made by consuming time by 256x256 step empty loop.

.def R_TEMP1	=R17
.def R_TEMP2	=R18
.def R_TEMP3	=R19
.def R_TEMP4	=R20

.equ	COUNT_START	= 0xFF;256
.equ	COUNT_END	= 0x01; counter end in delay loop
.equ	SUB_COUNT	= 0xFF;256
.equ	SUBNUM	=	0x01; subtract number in delay roop
.org 0x0010
	RJMP MAIN

MAIN:
	LDI R_TEMP1, 0B11111111 ;seting PORTB for output
	OUT DDRB, R_TEMP1;seting PORTB for output
	LDI R_TEMP2, 0B00001000 ;PB3=1(ON), rest are 0(OFF)
    OUT PORTB, R_TEMP2;PB3=1(ON), rest are 0(OFF)

LOOPPOINT:

	LDI R_TEMP2, 0B00001000
    OUT PORTB, R_TEMP2 ; setting PB3=1 (ON)
	RCALL	DELAY; calling subroutine delay
	LDI R_TEMP2, 0B00010000; setting PB4=1 (ON), rest are off
    OUT PORTB, R_TEMP2; setting PB4=1 (ON), rest are off
	RCALL	DELAY; calling subroutine delay
	RJMP LOOPPOINT ;jump to LOOPPOINT

DELAY:	; subroutine DELAY
	LDI	R_TEMP4, SUB_COUNT
SUB_COUNT1:
	LDI	R_TEMP3, COUNT_END
	LDI	R_TEMP1, COUNT_START
	LDI	R_TEMP2, SUBNUM
COUNTER:
	SUB	R_TEMP1, R_TEMP2
	CPSE	R_TEMP1, R_TEMP3
	RJMP COUNTER	
	SUB	R_TEMP4, R_TEMP2
	CPSE	R_TEMP4,	R_TEMP3
	RJMP	SUB_COUNT1
	RET	

This leads to 161 bytes .hex file.

Let's see next, by C by Atmel Studio C,

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

int main(void)
{
	unsigned int delay = 100;

	// Set up Port B pin 3 and 4 mode to output
	DDRB = 0b00011000;

	// Set up Port B for initial state (PB4=1, rest are 0)
	PORTB = 0b00010000;

	while (1) {
		// Toggle Port B pin 3 and 4
		PORTB ^= 1<<PB4;
		PORTB ^= 1<<PB3;
		// delay of delay ms
		_delay_ms (delay);
	}
}
I am not sure how it realises delay function (should be by timer) but the .hex file reads 255 bytes. We cannot see the bottom of Attiny by C ( we can, but if we use prepared function), but code side is not so big, indeed.

Now let's see the case of Arduino..

void setup() {
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}
void loop() {
  digitalWrite(3, LOW);   
  digitalWrite(4, HIGH);   
  delay(1000);             
  digitalWrite(3, HIGH);   
  digitalWrite(4, LOW);   
  delay(1000);              
}
We have no mysterious part (like DDRB and PORTB) and surely very easy to read. But in return, the produced .hex file size is.... 2929 bytes!!!I've thought Assembly will be the best for small binary production but indeed C is comparable. But making Assembly code teach me a lost of basis, like DDRB and register usage (which never appears in Arduino, since those setting is done by simple pinMode()).

I will go forward, step by step.... stay tune!

Discussions