Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # *************************************************
- # * Subroutine: sbc *
- # * Description: Subtract memory with accumulator *
- # *************************************************
- .global exe_sbc
- exe_sbc:
- enter
- andb $0b10111111, P # Clear overflow flag
- # %al = accumulator
- movzbl A, %eax # Read accumulator into eax
- # %bl = inverted memory
- movl ARG, %ebx # Read memory address into ebx
- movzbl (%ebx), %ebx # Read operand from memory into bl
- ## BCD conversion
- movb P, %dh # Load P for checking
- andb $0b00001000, %dh # Filter out everything but the decimal flag
- cmpb $0b00001000, %dh # Check if decimal flag is set
- jne sbc_nofrombcd
- pushl %ebx # Store ebx for later use
- pushl %eax # %eax as argument
- call frombcd # Convert from bcd to 2c
- addl $4, %esp # Clear %eax from stack
- popl %ebx # Retrieve %ebx
- pushl %eax # Save %eax for later use
- pushl %ebx # %ebx as argument
- call frombcd # Convert from bcd to 2c
- addl $4, %esp # Clear %ebx from stack
- movl %eax, %ebx # Move return value to %ebx
- popl %eax # Retrieve %eax
- sbc_nofrombcd:
- # %cl = carry
- movzbl P, %ecx # Read proc status flag into %ecx
- andb $0b00000001, %cl # Filter out everything but the carry
- pushl %eax # Push eax for overflow check
- pushl %ebx # Push ebx for overflow check
- # %bl = negative memory
- xorb $0b11111111, %bl # Bit-invert memory value for addition
- addl %ecx, %ebx # Add carry to inverted memory
- # %bl += %al
- addl %eax, %ebx # Add accumulator to negative memory
- pushl %ebx # Push result for overflow check
- call setsbcoverflow # Check overflow
- popl %ebx # Retrieve ebx
- addl $4, %esp # Skip over original ebx
- popl %eax # Retrieve eax
- pushl %ebx # Check carry
- call setcarry # ...
- popl %ebx # ...
- movb %bl, A # Store result back into accumulator
- movb P, %dh # Load P for checking
- andb $0b00001000, %dh # Filter out everything but the decimal flag
- cmpb $0b00001000, %dh # Check if decimal flag is set
- jne sbc_notobcd
- movzbl A, %eax # Reload A value
- pushl %eax # %eax as argument
- call tobcd # Convert from bcd to 2c
- addl $4, %esp # Clear %eax from stack
- movb %al, A # Put result back in A
- sbc_notobcd:
- pushl %eax # Affect
- call setzero # zero and
- call setneg # negative
- addl $4, %esp # flags.
- incw PC # Increment PC
- return
Add Comment
Please, Sign In to add comment