http://necrobious.blogspot.jp/2010/06/avr-asm-first-steps.html
Arduino(ATmega328p)で約1秒周期でBlinkする
16MHzなので、16M cycle(16メガサイクル)回せば1秒ディレイする。
Cで書くときとの違いはスタックポインタの初期化が必要になるところ。(SRAM最後尾への配置を明示)
.include "m328def.inc" .def temp = r16 .equ led = 5 ; PORTD bit number to blink LED on .def dly1 = r17 .def dly2 = r18 .def dly3 = r19 .org 0x0000 ; the next instruction will be written to 0x0000 rjmp main ; jump to main: main: ldi temp, low(RAMEND) ; initiate the stack in the build in SRAM. Stack operations out SPL, temp ; are always necessary when subroutines or interrupts are called. ldi temp, high(RAMEND) ; By calling the subroutine or interrupt handling routine the actual adress out SPH, temp ; is written to the stack in order to later jump back to the code where the ; interrupt or call occurred. sbi DDRB, led ; connect PORTD pin 4 to LED loop: cbi PORTB, led ; turn PD4 high rcall Delay_1sec ; delay for an short bit sbi PORTB, led ; turn PD4 low rcall Delay_1sec ; delay again for a short bit rjmp loop ; recurse back to the start of loop: Delay_1sec: ; For CLK(CPU) = 16 MHz ; 4cycle * 250 * 125 * (8*16) = 16,000,000(16メガサイクル) LDI dly1, 8*16 ; One clock cycle; Delay1: LDI dly2, 125 ; One clock cycle Delay2: LDI dly3, 250 ; One clock cycle Delay3: DEC dly3 ; One clock cycle NOP ; One clock cycle BRNE Delay3 ; Two clock cycles when jumping to Delay3, 1 clock when continuing to DEC DEC dly2 ; One clock cycle BRNE Delay2 ; Two clock cycles when jumping to Delay2, 1 clock when continuing to DEC DEC dly1 ; One clock Cycle BRNE Delay1 ; Two clock cycles when jumping to Delay1, 1 clock when continuing to RET RET
書き直し
.include "m328def.inc" .org 0x0000 rjmp reset reset: ldi R16,low(RAMEND) out SPL, R16 ldi R16,high(RAMEND) out SPH, R16 main: sbi DDRB, 5 loop: sbi PORTB,5 rcall delay cbi PORTB,5 rcall delay rjmp loop delay: ldi R17,16*4 delay1s: ldi R18,250 delay250ms: ldi R19,250 delay1ms: nop dec R19 brne delay1ms dec R18 brne delay250ms dec R17 brne delay1s ret