2013-03-09 101 views
0

我在bigavr板上有atmega1280的以下彙編代碼。AVR彙編邏輯運算

;Set PA3:0 to input without pull-up and PA7:4 to output and use PORTA7:4 for LED0-3. 

.nolist 
.include "m1280def.inc" 
.list 

.equ PORT, PORTA 
.equ DDR, DDRA 
.equ PIN, PINA 

.equ temp, 0x10 
.equ pa1, 0x11 
.equ pa2, 0x12 
.equ pa3, 0x13 

.section .text 
.globl main 
.org 0x0000 

    rjmp main 

main: 
main_init_stack_ptr: 
    ldi  temp, lo8(RAMEND) 
    out  SPL, temp 
    ldi  temp, hi8(RAMEND) 
    out  SPH, temp 

main_init_ports: 
    ldi  temp, 0x0 
    out  PORT, temp 
    ldi  temp, 0xf0   ;(PORTA index) 
    out  DDR, temp   ; oooo iiii (i/o state) 

main_loop: 
    in  temp, PIN 
    andi temp, 0x0f 

    rcall set_led0 

    out  PORT, temp 

    rjmp main_loop 

set_led0:      ; PORT << 4: (1 & 2) | 3 
    rcall prepare_operands 

    and  pa1, pa2 
    or  pa3, pa1 

    sbrs pa3, 0 
    ret 
    sbr  temp, 0b00010000 
    ret 


prepare_operands:    ; move inputs 1..3 to pa1..3 
    mov  pa1, temp   ; and shift/mask them the LSB 
    mov  pa2, temp 
    mov  pa3, temp 
    lsr  pa1 
    lsr  pa2 
    lsr  pa2 
    lsr  pa3 
    lsr  pa3 
    lsr  pa3 
    andi pa1, 0x01 
    andi pa2, 0x01 
    andi pa3, 0x01 
    ret 

的代碼應執行邏輯運算:LED0: (PA1^PA2) v PA3

但我不明白它是如何工作的。 我的假設: With in temp, PIN我可以讀出輸入引腳上的值。如果PORTA1和PORTA3被激活,PIN應返回00000101。好吧,在prepare_operands這是移動到變量pa1,pa2和pa3。對於pa1,它向右移動了一次。所以pa1包含00000010。在pa1上執行addi操作,爲什麼?這個怎麼用?

回答

0

我沒有在您發佈的代碼中看到任何addi指令。如果你的意思是andi那麼目的是掩蓋除了感興趣的那個之外可能已經設置的任何附加位。

temp設置爲PIN & 0xf,所以它可以在0x0..0xf範圍內有任何值。如果temp碰巧是0xf,而您只是將pa1設置爲temp >> 1,那麼您會得到0x7。但是因爲prepare_operands的意圖似乎是將第n位放置在pan中,所以它在移位之後(例如,0xf >> 1 == 0x7,0x7 & 1 == 1)進行按位AND。

1

代碼試圖在操作數中放置一個0x1,如果掩碼在某個位置有一點。

首先,pa1,pa2和pa3中的每一個被移位一個不同的數量,以便將最感興趣的位移到最右端。然後「和立即0x1」清除變量中除最右側以外的所有位,並保持最右側不變。

變量將包含0x0或0x1,具體取決於感興趣的位的值。