-
Notifications
You must be signed in to change notification settings - Fork 6
IF ELSE ENDIF directives
According to the original 8085 assembly programming manual, there are assembly-time directives such as IF,ELSE,ENDIF.
Much like a MACRO, IF/ELSE/ENDIF are directives. That means they "direct" the ASSEMBLER to do something.
They do not exist during run-time. And it is not the equivelant of "if" in C/C++. If anything, it is the equivelant of #if in C/C++.
Upon pressing Assemble, the assembler decides which code will be assembled.
After that, while running the program, the code to be executed has already been decided. "IF" is completely removed.
- In an IF statement, you can either compare two numbers, or compare two literals.
- The two numbers don't have to be in the same base. For example, you can compare 10 and 0AH.
- You can nest IF/ELSE/ENDIF statements.
- Comparisons between two numbers:
- EQ - Equal
- NEQ - Not equal
- LT - Less than
- LTE - Less than or equal
- GT - Greater than
- GTE - Greater than or equal
- Comparisons between two literals:
- EQ - Equal
- NEQ - Not equal
The most useful usecase is inside of a MACRO.
Let's say you have one MACRO that takes in a number, and if that number is less than FFH, you'll store it in B
But if that number is bigger than FFH, you'll store it in BC.
STORE MACRO n
IF n LTE FFH
MVI B,n
ELSE
LXI B,n
ENDIF
ENDM
STORE 10H ; B = 10H
STORE 2020H ; BC = 2020H
Since IF directive is an assembly-time only directive, that means you can't use it during run-time.
Let's say you want to compare Register A with 0.
You can't do IF A EQ 0
. That'll result in an error, because A
is a literal and 0
is a number.
A
does not get evaluated as the current value of the Register A, rather it's just the letter 'A'.
This ADDN MACRO, unlike the one in the MACRO examples, works for all Registers.
It also does affect flags, without affecting register A.
This example also shows nested IF statements.
; This MACRO uses the IF directive in order to make an
; instruction ADDN, which adds a number n to ANY
; register, including the Accumulator,
; and it also sets the flags properly.
; As we said, IF,ELSE,ENDIF are Assembly-time directives
; In this example, that means that each time you use this MACRO
; There might be completely different code being compiled.
; Calling "ADDN A,10H", will simply be the same as "ADI 10H", a 2 byte instruction
; But calling "ADDN B,10H", will be a lot more instructions
; Also, calling "ADDN D,10H", will also be different instructions,
; as _TEMP will be different.
ADDN MACRO R,n
IF R EQ A ; If R = A, then simply use ADI.
ADI n
ELSE
; If R = anything other than A,
; In order to modify the flags without modifying A
; We need another temporary register to hold A
; We cannot use PUSH/POP, that'd also not let flags
; Be modified
; Our temporary register cannot be the register R, for obvious reasons
; But, if R=C, then our temp register can't be B either
; Because then we'd need to "PUSH B",
; And that would affect register C.
; So...
IF R EQ B ; If our Register is B,
_TEMP EQU D ; Our temp will be D
ELSE
IF R EQ C ; Else if our register is C
_TEMP EQU D ; Our temp will still be D
ELSE ; Else if it's not B or C
_TEMP EQU B ; Our temp register will be B
ENDIF ; We need 2 ENDIF
ENDIF ; Because we have 2 IFs
PUSH _TEMP ; We push our _TEMP registers
MOV _TEMP,A ; Hold value of A in _TEMP
MOV A,R ; MOV R into A to do the calculation
ADI n ; ADI
MOV R,A ; Get the result back into R
MOV A,_TEMP ; Get original value of A back into A
POP _TEMP ; Get original value of _TEMP back.
ENDIF
ENDM
ADDN A,10H
HLT ; A = 10H, flags are set
ADDN B,20H
HLT ; B = 20H. A is still 10H, and flags are updated.
ADDN B,DFH
HLT ; B = FFH now.
; Since flags are affected, the sign flag, for example, is 1 because FFH is a negative number.