Vous êtes sur la page 1sur 6

Q1) a) [20 pts] For the following program, determine the contents of the RAM given below just

before the execution of SJMP $. Note that empty bit-or byte locations will be assumed to be 00h
before the program is run. The ROM address of the code is listed in the beginning of each
instruction.

ORG 0
0000 LJMP MAIN
CNT1 EQU 3
CNT2 EQU 2
CNT3 EQU 2

0003 DDATA: DB 124, 155, 88, 16h, 10h, 00100000b, 10011010b


LOC: DB 20h, 21h, 22h

ORG 0100h

0100 MAIN: MOV SP, #4Fh


0103 MOV DPTR, #DDATA
0106 MOV R1, #CNT1
0108 ACALL RDNEXT
010A MOV R1, #CNT2

010C ACALL RDNEXT


010E MOV R1, #CNT3
0110 ACALL RDNEXT
0112 SJMP $

ORG 0200h
0200 RDNEXT: PUSH ACC
0202 CLR A
0203 MOVC A,@A+DPTR
0204 RRC A
0205 CLR C
0206 ACALL CPDATA
0208 LOOP: INC DPTR
0209 DJNZ R1, LOOP
020B POP ACC
020D RET
ORG 0300H
0300 CPDATA: PUSH DPL
0302 PUSH DPH
0304 PUSH ACC

0306 MOV A, R2
0307 MOV DPTR, #LOC
030A MOVC A,@A+DPTR

030B INC R2
030C MOV R0, A
030D POP ACC
030F MOV @R0, A
0310 POP DPH
0312 POP DPL
0314 RET

END
b) [3 pts] What is the 16-bit signed representation of the decimal number -5689. Provide the result
in HEX form. Show your steps.

-5689 D = E9C7 H

c) [2 pts]
CLR C
MOV A,#05h
SUBB A,#0FF ; remember FFh is the signed representation of -1 and also the unsigned
; representation of 255.

Find the accumulator and the carry flag after these two instructions are executed. Is the carry an
indicator of a comparison of the decimal numbers 5 and -1 or 5 and 255? Show your steps.

A = 06H
C=1
comparison between 5 and 255

d) [10 pts] Assume that P1 port of an 8051 is connected to a circuit to receive 8 bit signed input.
We would like to write a subroutine with the name COUNTDATA which will read 10 consecutive
inputs in total, count the number of inputs which are strictly less than 20 and greater than or equal
to -20, and hold this count in R1 upon return. Fill in the missing parts accordingly. (Hint: Use
CJNE A,#data,rel for your comparisons.) Your program needs to fit in the provided space.

COUNTDATA: MOV P1, #0FFH ; make P1 an input port


CLR A ; initialize registers as necessary
MOV R1, A ;
MOV R0, #10 ;
RDPORT:MOV A, P1 ; read an input
ADD A, #20 ; check if the input is
CJNE A, #40, NXT ; between -20 and 20
NXT:JNC LOOPEND ; and update the count
INC R1 ; in R1
LOOPEND:DJNZ R0, RDPORT; continue until 10 readings are completed
RET

Other solutions with more lines are possible. But checking if the input that is smaller than 14h is
greater than or equal to ECh is not correct. e.g. -1d (=FFh which is not smaller than 14h) will be
ignored in such a check.
Q2) a) Consider the hardware connections as in the following figure, and find the values of
registers A, B, and R2 by filling in the boxes below. (Please note that you need to find the value of
register A just after the execution of the "MOV A, P1" instruction.)

ORG 0
MOV R3, #0A1h
MOV R5, #35h
MOV R7, #19h
MOV P1,#0FFh
MOV A, P1 ; A = __79__h
CLR C
SUBB A, #72h
MOV 1, A
MOV B, @R1 ; B = __19__h

MOV A, #0C3h
ANL P1, A
PUSH P1 ; (Hint: PUSH pushes the latch values for P1 onto the stack.)

MOV R2, 8 ; R2 = __C3__h

SJMP $
b) In the following program, the aim is to read 32 bytes of data (unsigned numbers) from the
internal ROM space starting from address 0200h, and then to copy the even numbers to internal
RAM locations starting from address 30h and the odd numbers to internal RAM locations starting
from address 50h. Complete the following program in order to perform the specified tasks.

ORG 0

MOV R5, #32 ; initialize R5 appropriately

; you can do any other initializations here


MOV DPTR,#0200h
MOV R0, #30h
MOV R1, #50h

REPEAT:
; read a byte from internal ROM
CLR A
MOVC A,@A+DPTR

; check if the byte read above is even or odd, and copy it to the appropriate RAM location.
; also perform necessary updates for the next round
; (no more than 10 instructions can be used in this box.)

JNB ACC.0, EVEN


MOV @R1,A
INC R1
SJMP NEXT
EVEN: MOV @R0,A
INC R0
NEXT: INC DPTR

DJNZ R5, REPEAT

SJMP $

ORG 0200h
DB ................................. ; there are 32 bytes of data that are not shown here.

END
Q3) For parts a) and b) of this question, we will write a subroutine with the name MULBCD to
multiply two single-byte packed BCD (Binary Coded Decimal) non-zero numbers that are read
from ports 0 and 1 and the product will be saved as BCD at the accumulator and R0, the low part
of the number in R0 and the high part in ACC. For example, we read 16h from Port 0 and we read
80h from Port 1, then we need to multiply 16d and 80d for which the product is 1280d therefore
location R0 should be 80h and ACC be 12h upon the return from MULBCD. For this purpose, we
MUST use the following algorithm: i) first convert the number in port 1 to hex and save the result
in R2 ii) Use the subroutine obtained in part i) and add the number in Port 0 to itself R2 times
while using decimal adjustment. Assume we are at bank 0. You can safely assume that P1 and P0
transistors are already off and you can readily read from P1 or P0.

a) [15 pts] Write a procedure with the name CONVERT that reads a BCD number from Port 1
and converts this into hex in R2. For example, when the number read is 80h (BCD of 80d)
we need to convert it to 50h which is the hex representation of 80d. Each row below is for
a single instruction and your program needs to fit into the provided space.

CONVERT:
PUSH ACC
MOV A,P1
MOV R1,A
ANL A,#0F0h
SWAP A
MOV B,#10
MUL AB
ANL 01h,#0Fh
ADD A,R1
MOV R2,A

POP ACC

RET
b) [20 pts] Now, write your procedure MULBCD as described previously, using the procedure
of part a) and NOT by using the MUL AB instruction. Obtain the packed BCD
representation of the product (1280h in the example) in the registers A and R0 (12h in ACC
and 80h in R0 for the example). Each row below is for a single instruction.

MULBCD:

MOV A,#00h ; initialize it to zero


LCALL CONVERT ; convert the number in port 1 to hex
MOV R0,#00h ; initialize it to zero
BACK: ADD A,P0
DA A
JNC SKIP
PUSH ACC
MOV A,R0
ADD A,#01
DA A
MOV R0,A
POP ACC
SKIP: DJNZ R2,BACK
XCH A,R0

RET