Литерал xorwf не влияет на флаг z, даже если литеральное значение совпадает со значением в w

В соответствии с описанием набора инструкций «xorwf myLiteral» должен выполнять операцию xor содержимого «w» с «myLiteral», и если оба они одинаковы, то должен быть установлен флаг Z в STATUS (не интересно, где эта инструкция сохраняет результат, но флаг Z должен быть затронут, если оба значения были одинаковыми)

Но в моем коде этого не происходит

movf PORTC
xorwf red_on    ;w holds 01000100 and red_on is also 01000100 Z must be one
btfsc STATUS, Z ;but here it's not one
goto Turn_Yellow_On

Полный код следующий:

    ; PIC16F72 Configuration Bit Settings

; Assembly source line config statements

#include "p16f72.inc"

; CONFIG
; __config 0xFFF7
 __CONFIG _FOSC_RC & _WDTE_ON & _PWRTE_ON & _CP_OFF & _BOREN_ON

STATUS equ 0x03
TRISC equ 0x87
PORTC equ 0x07
INTCON equ 0x0b

RP0 equ 5
RP1 equ 6
Z equ 2

GIE equ 7
INTE equ 4
INTF equ 1

all_off equ 0x00
red_on equ 0x44
yellow_on equ 0x22
green_on equ 0x11 

bank0 macro
    bcf STATUS, RP0
    bcf STATUS, RP1
    endm

bank1 macro
    bsf STATUS, RP0
    bcf STATUS, RP1
    endm

extrn_int_enable macro
    bsf INTCON, GIE
    bsf INTCON, INTE
    endm

PORTC_as_out macro
    bank1
    movlw 0x00
    movwf TRISC
    endm

PORTC_out macro outByte
    bank0
    movlw outByte
    movwf PORTC
    endm

test_and_switch macro testWith, jumpTo
    movf PORTC
    xorwf testWith
    btfsc STATUS, Z
    goto jumpTo
    endm

    org 0x00
Reset_Vector:
    goto Main

    org 0x04
Interrupt_Vector:
    goto Switch_Next

    org 0x05
Main:
    PORTC_as_out
    extrn_int_enable

Loop:
    clrwdt
    goto Loop

    org 0x200
Switch_Next:
    bcf INTCON, INTF

    ;test_and_switch all_off, Turn_Red_On
    movf PORTC      ;I recognized the mistake I should use d = 0 but data
    ;will still be copied in w when program goes to "Turn_Red_On" routine for 
    ;the first time
    xorwf all_off
    btfsc STATUS, Z
    goto Turn_Red_On

    ;test_and_switch red_on, Turn_Yellow_On
    movf PORTC
    xorwf red_on    ;w holds 01000100 and red_on is also 01000100 Z must be one
    btfsc STATUS, Z ;but here it's not one
    goto Turn_Yellow_On

    ;test_and_switch yellow_on, Turn_Green_On
    movf PORTC
    xorwf yellow_on
    btfsc STATUS, Z
    goto Turn_Green_On

    goto Turn_All_Off

Turn_Red_On:
    PORTC_out red_on
    goto Return_From_Int

Turn_Yellow_On:
    PORTC_out yellow_on
    goto Return_From_Int

Turn_Green_On:
    PORTC_out green_on
    goto Return_From_Int

Turn_All_Off:
    PORTC_out all_off
    goto Return_From_Int

Return_From_Int:
    retfie

    end

Ответы (1)

В вашей инструкции movf PORTC отсутствует пункт назначения.

По умолчанию используется f, в данном случае PORTC, поэтому вы не помещаете число в регистр w.

Измените его на movf PORTC, w

И вы всегда должны указывать это явно, чтобы предотвратить проблемы. Запуск симуляции, вероятно, уловил бы это, и стоит научиться это делать.

Редактировать: Кроме того, вы используете xorwf (бывший или регистр w с файловым регистром), когда вы должны использовать xorlw (бывший или литерал с регистром w).

xorwf принимает операнд как адрес и выполняет операцию xor над регистром w с содержимым регистра в этом месте (0x44, в 96 байтах регистров общего назначения), что вам не нужно.

пункт назначения результата не является достопримечательностью атм. Нежелательный результат - это когда w содержит 0x44, а xorwf 0x44 не устанавливает флаг Z (это меня удивляет). Если вы скопируете и смоделируете этот код в MPLAB X и используете стимул для прерывания вывода INT, вы заметите, что во втором прерывании после ввода метки Switch_Next примерно в 7-й строке кода вы заметите, что значение w будет равно 0x44 и "xorwf red_on" (red_on equ 0x44) по-прежнему не устанавливает Z в STATUS при выполнении, что странно
См. добавление редактирования выше.
Спасибо, это была моя ошибка, я не распознал, что xorwf принимает буквальное значение как адрес, а не как постоянное значение, теперь я заменил его на xorlw, и мой код работает. Благодарен Вам!