【问题标题】:AVR assembly logical operationAVR 汇编逻辑运算
【发布时间】:2013-02-25 04:12:58
【问题描述】:

我在 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,它向右移动一次。所以 pa1 包含00000010。在 pa1 上执行了 addi 操作,为什么?这是如何工作的?

【问题讨论】:

    标签: assembly avr


    【解决方案1】:

    如果掩码在某个位置有位,则代码会尝试在操作数中放置 0x1。

    首先,pa1、pa2 和 pa3 中的每一个都移动了不同的量,以将感兴趣的位移到最右端。然后 "and with immediate 0x1" 清除变量中除最右边之外的所有位,并保持最右边不变。

    变量将包含 0x0 或 0x1,具体取决于感兴趣位的值。

    【讨论】:

      【解决方案2】:

      我在您发布的代码中没有看到任何 addi 指令。如果您的意思是andi,那么目的是屏蔽除感兴趣的位之外可能已设置的任何其他位。

      temp 设置为 PIN &amp; 0xf,因此它可以具有 0x0..0xf 范围内的任何值。如果 temp 恰好是 0xf,而您只需将 pa1 设置为 temp &gt;&gt; 1,那么您将得到 0x7。但由于prepare_operands 的意图似乎是将第 n:th 位放在pan 中,它在移位后执行按位与(例如 0xf >>1 == 0x7, 0x7 & 1 == 1)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-27
        • 2020-07-18
        • 1970-01-01
        • 1970-01-01
        • 2020-12-20
        相关资源
        最近更新 更多