2017-05-21 87 views
2

我明白我可以用C編寫Arduino,但是使用我當前的項目(一個微小的Arduino內核),我真的更願意使用Assembly進行一些部分學習Assembly,並可能提高SLIGHTEST的效率。在裝配中編程Arduino?

有什麼我可以使用像__ASM __()?我只能真正在網上找到人,試圖說服那些提出類似問題的人學習C,而不是真正回答這個問題。

謝謝!

+0

內聯彙編是先進的,你應該先學習彙編語言,然後如果你真的有一個很好的理由,內聯彙編。您可以絕對使用匯編語言編寫AVR(在arduino上或不在)。 –

+0

那麼我將如何去編程裝配中的AVR?就像在C函數中使用的\ __ asm__標籤一樣? – LoganJamison

+0

不,這是內聯彙編... –

回答

3

我之前寫過並張貼過很久。

.device ATmega168 
.equ DDRB  = 0x04 
.equ PORTB  = 0x05 

.org 0x0000 
    rjmp RESET 

RESET: 
    ldi R16,0x20 
    out DDRB,R16 

    ldi R18,0x00 
    ldi R17,0x00 
    ldi R20,0x20 
Loop: 

    ldi R19,0xE8 
aloop: 
    inc R17 
    cpi R17,0x00 
    brne aloop 

    inc R18 
    cpi R18,0x00 
    brne aloop 

    inc R19 
    cpi R19,0x00 
    brne aloop 

    eor R16,R20 
    out PORTB, R16 
    rjmp Loop 

我用阿夫拉並有可能寫我自己的Arduino裝載機

blinker01.s.hex : blinker01.s 
    avra -fI blinker01.s 

clean : 
    rm -f blinker01.s.* 

可以使用,當然avr_dude。

使用GNU的東西有點不同:

.globl _start 
_start: 
    rjmp RESET 

RESET: 
    ldi R18,0x00 
    ldi R17,0x00 
    ldi R20,0x20 
Loop: 

    ldi R19,0xE8 
aloop: 
    inc R17 
    cpi R17,0x00 
    brne aloop 

    inc R18 
    cpi R18,0x00 
    brne aloop 

    inc R19 
    cpi R19,0x00 
    brne aloop 

    rjmp Loop 
你並不真正需要的頭文件來定義端口

,你可以聲明那些自己。

MEMORY 
{ 
    rom : ORIGIN = 0x00000000, LENGTH = 0x1000 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
} 

avr-as so.s -o so.o 
avr-ld -T so.ld so.o -o so.elf 
avr-objdump -D so.elf > so.list 
avr-objcopy so.elf -O ihex so.hex 

使用貼切,得到了AVR-GCC(和Binutils)可能與Arduino的沙箱使用,相同的工具應該是直接訪問的,但我不使用沙箱所以不知道。

編輯

另一種方法是有限的,但更可能是因爲你有一個工作的C程序和環境入手,然後添加一個對象與工具鏈要取得成功,還與議會基本幫助,看看編譯器然後去讀了它:

unsigned short fun (unsigned short x, unsigned short y) 
{ 
    return(x+y+5); 
} 

avr-gcc -c -O2 so.c -o so.o 
avr-objdump -D so.o 

00000000 <fun>: 
    0: 6b 5f   subi r22, 0xFB ; 251 
    2: 7f 4f   sbci r23, 0xFF ; 255 
    4: 86 0f   add r24, r22 
    6: 97 1f   adc r25, r23 
    8: 08 95   ret 

所以

創建so.s

.globl fun 
fun: 
    subi r22, 0xFB ; 251 
    sbci r23, 0xFF ; 255 
    add r24, r22 
    adc r25, r23 
    ret 



avr-as so.s -o so.o 
avr-objdump -D so.o 

00000000 <fun>: 
    0: 6b 5f   subi r22, 0xFB ; 251 
    2: 7f 4f   sbci r23, 0xFF ; 255 
    4: 86 0f   add r24, r22 
    6: 97 1f   adc r25, r23 
    8: 08 95   ret 

然後,而不是鏈接在C生成的對象,鏈接在程序集生產的對象,你必須學習通過實驗,你可以找出調用約定。

unsigned char fun (unsigned char x, unsigned char y) 
{ 
    return(x+(y<<1)); 
} 
00000000 <fun>: 
    0: 66 0f   add r22, r22 
    2: 86 0f   add r24, r22 
    4: 08 95   ret 

在這種情況下,r22中的第二個參數首先在r24中,返回值在r24中。所以22/23可能是較短項目的第一個參數,第二個是24/25。它也會在某處被記錄下來,編譯器也符合它,但是會有例外,如此編寫一個合適的例子來看看編譯器做了什麼,而不是假設一個例子中的所有內容都是關鍵的,即使你閱讀了文檔,它可能是模糊的或者使用在實驗之前可能沒有意義的術語。

+0

你會想看到那裏的各種例子,AVR不是你想要學習的第一個程序集(不是最後一個,它的哈佛架構性質使它非常痛苦,msp430或arm thumb(cortex-m)會你可以找到一個更好的開始,他們都可以找到(或者寫下一個下午)的指令集模擬器,並且在啤酒工具中免費使用,並且可以購買價格爲10美元左右的Arduino成本的一部分你只需插入並使用 –

+0

是的,肯定會閱讀一些示例代碼,幸運的是,我發現其中一個ATmega PDF在Assembly和C中都有示例代碼。我認爲這將是一個很好的開始謝謝你的幫助,我會記住你的建議! – LoganJamison