You are on page 1of 12

Nhóm 1

Nguyễn Diệp Phúc Bình 2210316


ĐOÀN MINH DŨNG 2210566
Trịnh Quốc Thành 2213151
Nguyễn Duy Phúc 2212623

1. Xác định mã máy và độ dài,số MC các lệnh sau:


(a) LDI R23,$FA
(b) MOV R6,R14
(c) DEC R7
(d) OUT PORTC,R4
(e) ADWI R26,5
a/ EF7AH 1 word 1MC
b/ 2C6EH 1 word 1MC
c/ 947AH 1 word 1MC
d/ B848H 1 word 1MC
e/ 9615H 1 word 1MC
2. Xác định mã máy và độ dài,số MC các lệnh sau,tại PC=0x100:
(a) RJMP THERE ,nhãn THERE đ/c=0x10AC
 1100 kkkk kkkk kkkk, k = offset
 Offset = 0x10AC – (0x100 + 1) = 0xFAB
 Mã máy : 1100 0000 1111 1010 1011
(b) RCALL THERE ,nhãn THERE đ/c=0x10AC
 1101 kkkk kkkk kkkk, k = offset
 Offset = 0x10AC – (0x100 + 1) = 0xFAB
 Mã máy: 1101 0000 1111 1010 1011
(c) RJMP BACK ,nhãn BACK đ/c=0x9B4
 Offset = 0x9B4 – (0x100 + 1) = 0x8B3
 Mã máy : 1100 0000 1000 1011 0011
(d) RCALL BACK ,nhãn BACK đ/c=0x9B4
 Offset = 0x9B4 – (0x100 + 1) = 0x8B3
 Mã mãy: 1101 0000 1000 1011 0011
3. Xác định mã máy và độ dài,số MC các lệnh sau,tại PC=0x200:
a) BRNE LOOP ( LOOP = 0x1E6)
K = LOOP – ( PC + 1 ) = -27 ( 110 0101 )
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 0 0 1 1 0 0 1 0 1 0 1 0
b) BREQ LOOP ( LOOP = 0X22A)
K = LOOP – ( PC + 1) = 41 ( 010 1001 )
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 0 1 0 1 0 1 0 0 1 0 1 0
c) BRCS LOOP ( LOOP = 0x209 )
K = LOOP – ( PC + 1 ) = 8 (000 1000 )
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 0 1 0 0 0 1 0 0 0 0 0 1
d) BRCC LOOP ( LOOP = 0X1F0 )
K = LOOP – ( PC + 1) = -17 ( 110 1111 )
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 0 0 1 1 0 1 1 1 1 0 0 1

4. Cho đoạn chương trình sau:


(a) Viết mã máy các lệnh trên
.ORG 0X100
LDI R18,0
1110 0000 0010 0000
LDI R29,0X01
1110 0000 1101 0001
LDI R28,0X0A
1110 0000 1110 1010
LDI R19,10
1110 0000 0011 1010
TIEP: ST -Y,R18
1001001 10010 1010
DEC R19
1001010 10011 1010
BRNE TIEP
111101 111110 1001
(b) Tính thời gian thực thi đoạn chương trình trên
Tổng là 7 CK máy => tổng tg thực thi là 125ns*7=875ns

(c) Cho biết ý nghĩa đoạn chương trình trên


Đoạn chương trình này khởi tạo một số giá trị cho các thanh ghi (R18, R29, R28, R19),
sau đó thực hiện một vòng lặp (TIEP) 10 lần. Trong mỗi lần lặp, nó lưu giá trị của R18
vào vị trí nhớ được chỉ định bởi Y (một con trỏ được tạo từ R29 và R28), sau đó giảm Y
và R19. Nếu R19 không bằng 0, nó quay lại TIEP và tiếp tục vòng lặp. Điều này có thể
được sử dụng để khởi tạo một vùng nhớ với một giá trị cụ thể.

5. Xem đoạn chương trình sau:


LDI R17,$D5
LDI R18,$B9
ADD R17,R18
SUBI R17,$9F
MUL R17,R18
(a) Cho biết nội dung của các thanh ghi ảnh hưởng theo mỗi dòng lệnh
(b) Cập nhật trạng thái các cờ theo mỗi dòng lệnh
LDI R17,$D5 ; R17=D5 CÁC CỜ KHÔNG ĐỔI
LDI R18,$B9 ; R18=B9 CÁC CỜ KHÔNG ĐỔI
ADD R17,R18 ; R17=R17+R18 CỜ S,N,C LÊN 1
SUBI R17,$9F ; R17=R17-$9F CỜ H LÊN 1
MUL R17,R18 ; R1:R0=R17*R18 CÁC CỜ KHÔNG ĐỔI

6. Mô tả hoạt động của PC và stack khi thực thi đoạn chương trình sau:
PC(H) Lệnh
0F00 RCALL OUT_P ;stack 0x08FF = 0x01, 0x08FE = 0x0F, PC = 0x1000
0F01 LDI R17, 0; PC = 0x0F02, R17 = 0
...
1000 OUT_P:PUSH R17 ; stack 0x08FD = R17
1001 PUSH R16 ; stack 0x08FC = R16
1002 RCALL DELAY ;stack 0x08FB = 0x03, 0x08FA = 0x10, PC = 0x11A8, SP = 0x08F9
1003 POP R16 ; R16 = (0x08FC)
1004 POP R17 ; R17 = (0x08FD), SP = 0x08FD
1005 RET ; PC = Stack = 0x0F01, SP = 0x08FF

11A8 DELAY:…. ; PC = 0x11A9
….
11B6 RET ; PC = 0x1003, SP = 0x08FB
7. Viết một đoạn lệnh thực hiện:
(a) Dịch trái 1 số nhị phân 16 bit R21:R20(R21 byte cao)
(b) Quay trái 1 số nhị phân 16 bit R21:R20
LDI R20,0B00001111
LDI R21,0B11110000
LDI R22,0B01101001
LDI R23,0B11010101

ADD R20,R20; DICH TRAI R20


ROL R21;
ADD R22,R22;
ROL R23;
LDI R16,0
ADC R22,R16;

8. Viết một đoạn lệnh nhận dạng cạnh xuống xuất hiện trên PB1
LDI R17,0
OUT DDRB,R17
LDI R17, $FF
OUT PORTB, R17
LDI R17,$FF
OUT DDRA,R17
LDI R19,1
LDI R20,0

LOOP:
IN R16 ,PINB
BST R16,1
BLD R21,0
CPSE R21,R19
JMP LOOP
LOOP1:
IN R16 ,PINB
BST R16,1
BLD R21,0
CPSE R21,R20
JMP LOOP1
INC R18
OUT PORTA,R18
JMP LOOP

U1 R1
40 37
PB0/XCK0/T0/PCINT8 PA0/ADC0/PCINT0
41 36 300
PB1/T1/CLKO/PCINT9 PA1/ADC1/PCINT1
42
PB2/AIN0/INT2/PCINT10 PA2/ADC2/PCINT2
35 D1
43 34 LED-RED
PB3/AIN1/OC0A/PCINT11 PA3/ADC3/PCINT3
44 33
PB4/SS/OC0B/PCINT12 PA4/ADC4/PCINT4
1 32
PB5/MOSI/PCINT13 PA5/ADC5/PCINT5
2 31
PB6/MISO/PCINT14 PA6/ADC6/PCINT6
3 30
PB7/SCK/PCINT15 PA7/ADC7/PCINT7
9 19
PD0/RXD0/PCINT24 PC0/SCL/PCINT16
10 20
PD1/TXD0/PCINT25 PC1/SDA/PCINT17
11 21
PD2/INT0/RXD1/PCINT26 PC2/TCK/PCINT18
12 22
PD3/INT1/TXD1/PCINT27 PC3/TMS/PCINT19
13 23
PD4/OC1B/XCK1/PCINT28 PC4/TDO/PCINT20
14 24
PD5/OC1A/PCINT29 PC5/TDI/PCINT21
15 25
PD6/ICP/OC2B/PCINT30 PC6/TOSC1/PCINT22
16 26
PD7/OC2A/PCINT31 PC7/TOSC2/PCINT23
29 8
AREF XTAL1
27 7
AVCC XTAL2
4
RESET
ATMEGA324P

9. Viết một đoạn chương trình chuyển 1 chuỗi data có ký tự kết thúc chuỗi=$00 cất trong bộ
nhớ Flash địa chỉ đầu=TAB,sang vùng nhớ SRAM địa chỉ đầu=S_BUF(Các ký hiệu đã định
nghĩa trước)
.EQU TAB=$0200 ; ĐỊA CHỈ ĐẦU CỦA ROM
.EQU S_BUF=$0200 ; ĐỊA CHỈ ĐẦU CỦA SRAM THAY
; CẢ 2 ĐỊA CHỈ THAY ĐỔI KHI CẦN
.ORG 0
LDI ZH,HIGH(TAB<<1)
LDI ZL,LOW(TAB<<1)
LDI R16,0 ; LÀM BỘ ĐẾM ĐỊA CHỈ
LDI R17,0 ; LÀM SỐ 0 ĐỂ SO SÁNH
LDI XH,HIGH(S_BUF)
LDI XL,LOW(S_BUF)

LOOP:
ADD ZL,R16
ADC ZH,R17 ;NẾU ZL TRÀN THÌ CỘNG CARRY QUA ZH
LPM R18,Z
CP R18,R17
BRNE NEXT ; NẾU R18 KHÁC 0 THÌ CHUYỂN VÀO SRAM
RJMP OUT_LOOP ; NẾU R18 BẰNG 0 THÌ THOÁT KHỎI VÒNG LẶP
NEXT:
ADD XL,R16
ADC XH,R17
ST X,R18
INC R16
RJMP LOOP
OUT_LOOP:
10. Viết một chương trình đọc data từ PORTD,nếu data=$20 - $7F xuất ra PORTB,nếu data
$7F xuất ra PORTB=$00.Thực hiện lặp vòng liên tục.
LDI R16, $FF
OUT DDRB, R16 ;Cấu hình xuất cho PORTB
LOOP:
IN R16, PIND ;Nhập giá trị cho PORTD
MOV R17, R16
SUBI R16, $20
BRLT OUT_2 ;Nếu R16 - $20 < 0, OUT 2,R16 = $8X => Auto < 0
SUBI R16, $5F
BREQ OUT_1 ;R16 =$7F
OUT_1:
OUT PORTB, R17
RJMP LOOP
OUT_2:
LDI R17, $00
OUT PORTB, R17
RJMP LOOP

11. Viết một chương trình đọc byte data từ PORTA,dò từ LSB nếu gặp bit0 đầu tiên xuất
bit0 đúng vị trí trọng số ra PORTC,nếu không có bit0,xuất $FF ra PORTC,lặp vòng liên tục.
LDI R16, 0X00
OUT DDRA, R16
LDI R16, 0XFF
OUT PORTA, R16
OUT DDRC, R16

LDI R31, 0XFF


LDI R17, 7
LDI R18, 0B00000001
LOOP:
IN R16, PINA
AND R16, R18
BRNE BOQUA
COM R18
OUT PORTC, R18
JMP EXIST
BOQUA:
LSL R18
SUBI R17, 1
BRPL LOOP
OUT PORTC, R31
EXIST:
NOP

12. Viết một chương trình con tên COMP16 so sánh 2 số nhị phân 16 bit cất trong R21:R20
và R19:R18, kết quả trả về C=1 nếu R21:R20 < R19:R18,C=0 nếu R21:R20 ≥ R19:R18,bảo
toàn nội dung các thanh ghi.
LDI R16,1
OUT DDRB, R16

LDI R18,35
LDI R19,171
LDI R20,21
LDI R21,79

RCALL COMP6
RETURN:
BRCC LOOP
INC R17
LOOP:
OUT PORTA,R17
JMP END
COMP6:
MOV R22,R19
MOV R23,R21
CPSE R23,R22
JMP JUMP2
JMP JUMP
JUMP2:
SUB R23,R22
JMP RETURN
JUMP:
MOV R22,R18
MOV R23,R20
CPSE R23,R22
JMP JUMP1
JMP RETURN
JUMP1:
SUB R23,R22
JMP RETURN
END:

13. Viết một chương trình con tên ADD16 cộng 2 số nhị phân 16 bit,trả về: reg. số bị
cộng(16)←reg. số bị cộng(16)+reg. số cộng(16),C=1 nếu kết quả tràn
; cộng 2 số 16 bit
; lưu 2 số lần lượt vào thanh ghi x và y
; chương trình dưới đây giả sử đã lưu 2 số vào thanh ghi x và y bằng lệnh mov rồi
; LƯU KẾT QUẢ VÀO X

ADD XL,YL
ADC XH,YH

14. Viết một chương trình con tên SUB16 trừ 2 số nhị phân 16 bit,trả về: reg. số bị
trừ(16)←reg. số bị trừ(16) – reg. số trừ(16), C=1 nếu kết quả tràn(âm)
.ORG 0
LDI R17, $8F
LDI R18, $35
LDI R20, $FF
LDI R21, $10
RCALL SUB16
RJMP END

SUB16:
.DEF HED = R17 ;R17 là byte cao số bị trừ
.DEF LED = R18 ;R18 là byte thấp số bị trừ
.DEF HM = R20 ;R20 là byte cao số trừ
.DEF LM = R21 ;R21 là byte thấp số trừ
SUB LED, LM ;kết quả byte cao lưu vào R17
SBC HED, HM ;kết quả byte thấp lưu vào R18
RET
END:
15. Viết một chương trình con tên MUL16_8,nhân số nhị phân 16 bit cho 8 bit,trả về kết quả
24 bit: KQ=reg. số nhân(8):reg. số bị nhân(16)←reg. số bị nhân(16)xreg. số nhân(8)
LDI R16, 0XF0
MOV R17, R16; R17:R16 = F0F0
LDI R18, 0XAA;
LDI R31, 0X00

MUL R16, R18; R1:R0 16 BIT


MOVW R2, R0
MUL R17, R18;
MOVW R4, R0
ADD R3, R4
ADC R5, R31;
MOV R4, R5

16. Viết một chương trình con tên DIV16_8 chia số nhị phân 16 bit cho 8 bit,sử dụng phép
dịch bit và trừ (xem lại giải thuật phép chia nhị phân).Kết quả trả về thương số 16 bit(đặt
trong thanh ghi số bị chia) và dư số 8 bit.
LDI R16,0B10000001
LDI R17,0B00010000
LDI R18,0B00000010

RCALL DIV16_8
JMP END

DIV16_8:
CLR R20
SUB R16,R18
SBC R17,R20
BRCS NEXT
ADIW R24,1
JMP DIV16_8
NEXT:
ADD R18,R16
MOV R16,R24
MOV R17,R25
RET
END:

17. Viết một đoạn chương trình thực hiện phép tính: y=x2 -x+1,x=8 bit,y=16 bit
; ta GIẢ SỬ ĐÃ lưu x vào r16
; kết quả của phép tính lưu vào r1:R0

LDI R17,0 ; R17 = 0


MUL R16,R16 ; TÍNH X^2
SUB R0,R16
SBC R1,R17 ; TRỪ YHIGH CHO CARRY
INC R0
ADC R1,R17 ; CỘNG 1
18. Viết một chương trình con tên BCD_HEX8 chuyển số BCD thành số HEX:input
R17(BCD)=00-99, output R17(HEX)=$00-$63.

Thuật toán với 2 byte: BCD(HEX) = BCD – 6 * BCD(HEX7…4)


.ORG 0
LDI R16, $00
OUT DDRA, R16
LDI R16, $FF
OUT PORTA, R16
IN R17, PINA ;cấu hình nhập cho PINA
RCALL BCD_HEX8
RJMP END
BCD_HEX8:
MOV R18, R17 ;R18 = R17
SWAP R18
ANDI R18, $0F ;lấy byte cao R18 đưa thành byte thấp
LDI R19, $06
MUL R18, R19 ;R18 * 6
SUB R17, R0; R17 = R17 - R18 * 6
RET
END:
ADD R0, R0

19. Viết một chương trình con tên ADD_BCD cộng 2 số BCD(00-99),trả về kết quả số
BCD(00-99)và C=1 nếu kết quả tràn.
LDI R16, 0X00
OUT DDRA, R16
OUT DDRB, R16
LDI R16, 0XFF
OUT PORTA, R16
OUT PORTB, R16
OUT DDRC, R16; PORTA,B IN; PORT C OUT

IN R16, PINA
IN R17, PINB
LDI R31, 0X0F
LDI R30, 0X06
AND R16, R31
AND R17, R31
ADD R16, R17
CPI R16, 0X0A; R16 - 0X09
BRMI TIEP
ADD R16, R30; DONVI CHUA HIEU CHINH
MOV R17, R16
AND R16, R31; DONVI

TIEP:
IN R18, PINA
IN R19, PINB
LDI R31, 0XF0
LDI R30, 0X06
AND R18, R31
AND R19, R31
AND R17, R31
ADD R18, R19
ADD R18, R17
CPI R18, 0XA0; R18 - 0X90
BRMI EXIST
ADD R18, R30
ADD R16, R18
EXIST:
OUT PORTC, R16

20. Viết một chương trình con tên SUB_BCD trừ 2 số BCD(00-99),trả về kết quả số
BCD(00-99)và C=1 nếu kết quả tràn(âm)
LDI R16,5
LDI R17,0
LDI R18,2
LDI R19,1

LDI R20,9
LDI R21,6
NEG R18
NEG R19

ADD R18,R20
ADD R19,R20

ADD R16,R18
BRHC JUMP1
INC R22
JUMP1:
CP R20,R16
BRPL JUMP2
ADD R16,R21
BRHC JUMP2
INC R22
JUMP2:
ADD R17,R22
CLR R22
ADD R17,R19
BRHC JUMP3
INC R22
JUMP3:
CP R20,R17
BRPL JUMP4
ADD R17,R21
BRHC JUMP4
INC R22
JUMP4:
CPSE R22,R23
JMP JUMP5
NEG R16
ADD R16,R20
NEG R17
ADD R17,R20
SEC
JMP END
JUMP5:
SEC
ADC R16,R23
ADC R17,R23
END:
LDI R24,15
AND R16,R24
AND R17,R24

21. Viết một chương trình con tạo thời gian trễ 1ms,10ms,100ms,sử dụng cùng 1 chương
trình con chỉ khác biến nhập thay đổi thời gian
.MACRO DELAY ; DELAY_ 1ms * @0
LDI R17,@0
L1:
LDI R18,33
L2:
LDI R19,80
L3:
DEC R19
BRNE L3
DEC R18
BRNE L2
DEC R17
BRNE L1
.ENDMACRO

Đây là macro tạo delay 1ms với biến thay đổi là thời gian:
Ví dụ với lệnh DELAY k , với k là số trong hệ thập phân sẽ tạo thời gian delay là k ms

22. Viết một chương trình tạo chuỗi xung vuông đối xứng tần số 1Khz,xuất ra PB5
Fosc = 8MHz, 1MC = 0.125 μs
F = 1Khz, T = 1000 μs. Thời gian 1 trạng thái T/2=500 μs
Vậy ta cần tốn 500/0.125 = 4000MC cho trạng thái của xung.
.ORG 0
SBI DDRB, 5
LDI R16, 32
RELOOP:
RCALL LOOP ;3MC
IN R17, PORTB ;1MC
EOR R17, R16 ;1MC
OUT PORTB, R17 ;1MC
RJMP RELOOP ;2MC
LOOP:
NOP ;1MC
LDI R19, 249 ;1MC
LDI R20, 249 ;1MC
LDI R21, 249 ;1MC
LDI R22, 249 ;1MC
DELAY_1:
NOP ;1MC
DEC R19 ;1MC
BRNE DELAY_1 ;2/1MC
DELAY_2:
NOP ;1MC
DEC R20 ;1MC
BRNE DELAY_2 ;2/1MC
DELAY_3:
NOP ;1MC
DEC R21 ;1MC
BRNE DELAY_3 ;2/1MC
DELAY_4:
NOP ;1MC
DEC R22 ;1MC
BRNE DELAY_4 ;2/1MC
RET ;4MC
Sai số 1MC
23. Viết một chương trình tạo chuỗi xung vuông tần số 1Khz,CKNV=30%,xuất ra PD7
.ORG 0
SBI DDRD, 7

LOOP: SBI PORTD, 7


RCALL DELAYS_300US
CBI PORTD, 7
RCALL DELAYS_300US
RJMP LOOP

DELAYS_300US:
LDI R16, 3
LOOP2: LDI R17, 200
LOOP1: DEC R17;1MC
NOP;1MC
BRNE LOOP1; 2MC DUNG/ 1MC SAI
DEC R16; 1MC
BRNE LOOP2; 2MC DUNG/ 1 MC SAI
RET; 4MC

You might also like