0

bigavr ボード上の atmega1280 の次のアセンブリ コードがあります。

;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          ; 7654 3210 (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

しかし、私はそれがどのように機能するのか理解していません。私の仮定:私in temp, PINは入力ピンの値を読み取ることができます。PORTA1 と PORTA3 が有効化されている場合、PIN は を返し00000101ます。さて、prepare_operandsこれは変数 pa1、pa2、および pa3 に移動されます。pa1 の場合、右に 1 回シフトされます。したがって、pa1 には が含まれます00000010。pa1 でaddi操作が実行されますが、なぜですか? これはどのように作動しますか?

4

2 に答える 2

1

マスクの特定の位置にビットがある場合、コードはオペランドに 0x1 を配置しようとしています。

最初に、pa1、pa2、および pa3 のそれぞれが異なる量だけシフトされ、関心のあるビットが右端に移動されます。次に、「and with immediate 0x1」は、変数の右端を除くすべてのビットをクリアし、右端を変更しません。

対象のビットの値に応じて、変数には 0x0 または 0x1 が含まれます。

于 2013-03-09T20:51:45.613 に答える
0

addiあなたが投稿したコードには指示がありません。つまりandi、目的は、対象のビット以外に設定されている可能性のある追加のビットをマスクすることです。

tempに設定されてPIN & 0xfいるため、0x0..0xf の範囲の任意の値を持つことができます。tempたまたま 0xf に設定するpa1temp >> 1、0x7 になります。しかし、 の意図はprepare_operandsn 番目のビットをpan に配置することであるように見えるため、シフト後にビットごとの AND を実行します (例: 0xf >>1 == 0x7, 0x7 & 1 == 1)。

于 2013-03-09T19:07:16.697 に答える