Physically, the work of a microcontroller can be explained as a cycle of reading instructions stored in memory. The microcontroller determines the address of the program memory to be read, and performs the process of reading data in memory. The data read is interpreted as an instruction. The instruction address is stored by the microcontroller in a register, known as the program counter. This instruction is for example an arithmetic program involving 2 registers. The facilities available in the assembly program are very minimal, unlike in high-level programming languages where everything is ready to use. The writer of the assembly program must determine everything, determine the location of the program he wrote in the program memory, create constant data and constant tables in the program memory, create variables used to work in the data memory and so on.
Getting to Know Assembly Language
1. Assembly source program
Assembly source program is a collection of command lines written with a simple text editor program, such as the EDIT.COM program in DOS, or the NOTEPAD program in Windows or MIDE-51. The collection of command lines is usually saved into a file with the extension name *.ASM and so on, depending on the Assembler program that will be used to process the assembly source program.
Each command line is a complete command, meaning a command cannot be broken into more than one line. One command line can consist of 4 parts, the first part is known as a label or often also called a symbol, the second part is known as an operation code, the third part is an operand and the last part is a comment. Between these parts are separated by a space or tabulator.
Label section
Labels are used to name a command line, so that it can be easily referred to in writing programs. Labels can be written anything as long as they start with a letter, usually no more than 16 letters long. The following letters may be numbers or periods and underscores. If a command line does not have a label section, then this section may not be written but a space or tabulator as a separator between the label and the next section must still be written.
In a source program there can be many labels, but there must not be any duplicate labels.
Often a command line consists only of a label section, such a line cannot be said to be a real command line, but only gives a name to the line in question.
The label section is often also called the symbol section, this occurs if the label is not used to mark the program section, but is used to mark the data section.
Operation code section
Operation code (often abbreviated as OpCode) is a part of the command that must be executed. In this case, two types of operation codes are known, the first is the operation code to regulate the work of the microprocessor / microcontroller. The second type is used to regulate the work of the assembler program, often called the assembler directive.
Operation codes are written in mnemonic form, which is a relatively easy to remember abbreviation, for example MOV, ACALL, RET and so on. These operation codes are determined by the microprocessor/microcontroller manufacturer, thus each processor has a different operation code.
Mnemonic operation codes are not recognized by the microprocessor/microcontroller, so that programs written with mnemonic codes can be used to control the processor, such programs are translated into programs formed from binary operation codes, which are recognized by the microprocessor/microcontroller.
The translation task is carried out by a program called the Assembler Program.
Apart from the operation codes specified by the microprocessor/microcontroller manufacturer, there are also operation codes to regulate the work of the assembler program, for example used to determine the location of the program in memory (ORG), used to form variables (DS), form tables and constant data (DB, DW) and so on.
Operand section
Operands are complementary parts of the operation code, but not all operation codes require operands, so a command line can only consist of operation codes without operands. On the other hand, there are also operation codes that require more than one operand, in this case between one operand and another is separated by a comma.
The form of operands varies greatly, it can be codes used to state Registers in the processor, it can be memory numbers (memory addresses) stated with numbers or label names, it can be data ready to be operated on. All are adjusted to the needs of the operation code.
To distinguish between operands in the form of memory numbers or operands in the form of data ready to be operated on, special signs or different writing methods are used.
In addition, the operands can be simple mathematical equations or Boolean equations, in this case the Assembler program will calculate the value of the equations in the operands, then change the results of the calculation to binary code that is understood by the processor. So the calculation in the operands is done by the assembler program not by the processor!
Comments section
The comment section is the program author's notes, this section, although not absolutely necessary, is very helpful for documentation issues. Reading the comments on each command line, you can easily understand the purpose of the line in question, this is very helpful for other people who read the program.
The separator of the comment section from the previous section is a space or tabulator, although the first letter of the comment is often a semicolon, which is a special separator for comments.
For intensive documentation purposes, often a line is simply a comment, in which case the first letter of the line is a semicolon. The AT89S51 has a very complete set of instructions. The MOV instruction for byte is grouped according to addressing modes. Addressing modes describe how the operands are operated on. The various addressing modes are explained below. A common assembly program format is as follows:
| Label/Simbol | Opcode | Operand | Komentar |
|-----------------------------------------------|-------------------------------------------------------------|----------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
| | Org | 0H | |
| Start: Kiri: Delay: Del1: Del2: | Mov Mov Mov Call RL DEC CJNE Sjmp mov mov djnz djnz ret end | A, #11111110b R0, #7 P0, A Delay A R0 R0, #0, Kiri Start R1, #255 R2, #255 R2, del2 R1, del1 | ; Isi Akumulator ; Isi R0 dengan 7 ; Copy A ke P0 ; Panggil Delay |
The memory contents are hexadecimal numbers recognized by our microcontroller, which are a representation of the assembly language we have created. Mnemonic or opcode is the code that will perform an action on the operand. Operand is the data processed by the opcode. An opcode can require 1,2 or more operands, sometimes it doesn't need operands. While comments can be given by using a semicolon ( . Here are examples of different numbers of operands in an assembly.
CJNE R5,#22H, aksi ;dibutuhkan 3 buah operand
MOVX @DPTR, A ;dibutuhkan 2 buah operand
RL A ;1 buah operand
NOP ; tidak memerlukan operand
The program that we have finished making can be saved with the extension .asm. Then we can create an object program with the extension HEX using the MIDE-51 compiler, which is explained as follows:
2. Assembly Listing
The assembly source program above, after being written is submitted to the Assembler program to be translated. Each processor has its own assembler program, even one type of processor can have several types of Assembler programs made by different software manufacturers.
The main result of Assembler program processing is an object program. This object program can be a separate file, containing codes that are ready to be sent to the microprocessor/microcontroller program memory, but there are also object programs that are inserted into the assembly source program as seen in the Assembly Listing in Figure 2.
The right side of Figure 2 is the original Assembly source program by the program author. After being translated by the Assembler program, the resulting codes along with the memory numbers where the codes are stored are inserted on the left side of each command line, so that the form of this program is no longer called an assembly source program but is called an Assembly Listing.
Reading Assembly Listings can provide a clearer picture of the program being written. For beginners, Assembly Listings provide a deeper understanding of the contents of program memory, so that you can better imagine how a program works.
1: Org 0H
2: 0000 74 FE Start: Mov A,#11111110b
3: 0002 78 07 Mov R0,#7
4: 0004 F5 80 Kiri: Mov P0,A
5: 0006 12 00 1C Call Delay
6: 0009 23 RL A
7: 000A 18 DEC R0
8: 000B B8 00 F6 CJNE R0,#0,Kiri
9: 000E 78 07 Mov R0,#7
10: 0010 F5 80 Kanan: Mov P0,A
11: 0012 12 00 1C Call Delay
12: 0015 03 RR A
13: 0016 18 DEC R0
14: 0017 B8 00 F6 CJNE R0,#0,Kanan
15: 001A 80 E4 Sjmp Start
16: ;
17: 001C 79 FF Delay: mov R1,#255
18: 001E 7A FF Del1: mov R2,#255
19: 0020 DA FE Del2: djnz R2,del2
20: 0022 D9 FA djnz R1,del1
21: 0024 22 ret
22: end
Program 1.1: FIRST.ASM
;-----------------------------------------------------
; Nama Berkas : 11.ASM
; Pemrogram : Mahyuddin
; ----------------------------------------------------
%Title ”Judul – Tidak dirakit”
IDEAL
DOSSEG
MODEL TINY
; ----- Ditempatkan tetapan di sini
DATASEG
; ----- Deklarasi peubah dan nilainya Pesan DB ’Program pertama dengan bahasa’
DB ’rakitan’,13,10,’$’
; ----- Penentuan alamat awal model berkas
CODESEG
ORG 100h ; Alamat berkas bermarga .COM
; ----- Tubuh program atau subrutin
Mulai : MOV AH,09h MOV DX,OFFSET Pesan
INT 21h ; Sela tampilan Sistem Operasi
; (DOS dan Window)
; ----- Akhir sebuah program
INT 20h ; Sela SO kembali ke SO
END Mulai
The header will start an assembly language program. The header contains various commands and directives, none of which will be assembled into machine language, but their general function will be consistent with how a program is generated. In the program above, %Title states the intent of the program as a title, the MODEL TINY directive and the IDEAL directive state the selected program mode which is only valid in Turbo Assembler (TASM), and can be changed to Program 1.2.
Program 1.2: PERTAMB.ASM
;-----------------------------------------------------
; Nama Berkas : 12.ASM
; Pemrogram : Mahyuddin
; ----------------------------------------------------
PengSandi SEGMENT
ASSUME CS:PengSandi
ORG 100h
Mulai : JMP Awal Pesan
DB ’Program pertama’
DB ’dengan bahasa rakitan’,13,10,’$’
Awal : MOV AH,09h
MOV DX,OFFSET Pesan
INT 21h
INT 20h
Dude Compile Program Assembly ke *COM
To create a .COM program that only uses 1 segment, you can create it with a program model like figure 6.1. The form used here is the recommended program form (Ideal). The selection of the ideal program form in this book is due to considerations of the various advantages of this ideal program form, such as the process is faster and easier to use by various well-known high-level languages (Turbo Pascal and C).
Figure 6.1. COM Program Model
To make the ideal program form clearer, let us explore the form of this program further.
1. Model SMALL
This directive mark is used to inform the assembler of the memory format used by our program. To make it clearer, the models that can be used are:
TINY
If your program only uses 1 segment like a COM program. This model is provided specifically for COM programs.
SMALL
If the data and code used by the program is less than the size of 1 segment or 64 KB.
MEDIUM
If the data used by the program is less than 64 KB but the code used can be more than 64 KB.
COMPACT
If the data used can be larger than 64 KB but the code is less than 64 KB.
LARGE
If the data and code used by the program can be more than 64 KB.
HUGE
If the data, code or array used can be more than 64 KB.
Some may wonder why the COM program created uses the SMALL model instead of TINY? This is because many high-level language compilers cannot communicate with the TINY model, so we use the SMALL model as a solution.
2. CODE
This directive mark is used to inform the assembler that we will start using its Code Segment here. This code segment is used to store the program that will be run later.
3. ORG 100h
In COM programs this command will always be used. This command is used to tell the assembler so that the program when run (loaded into memory) is placed starting at offset 100h (256) bytes. It can also be said that we provide 100h empty bytes when the program is run. These 100h empty bytes will later be occupied by the PSP (Program Segment Prefix) of the program. This PSP is used by DOS to control the running of the program.
4. JMP
The JMP(JUMP) command is used to jump to the place indicated by the JUMP command. The syntax is:
JUMP Destination
Where the goal can be a label as used in the chart above. Regarding this JUMP command, we will discuss it further later.
The JUMP command used in the chart above is intended to skip the program data location, because if there is no JUMP command, the program data will also be executed, which will most likely cause your program to hang.
5. INT 20h
The INT command is a command to generate an interrupt with the syntax:
INT NoInt
Interrupt 20h serves to end the program and hand over full control to Dos. In COM programs this method is not the only one but this is the most effective way to use. If you forget to end a program then your program will not know when to finish, this will cause the computer to hang.
Assembly Programming Addition Operation
1. ADD
To add in assembler language, the ADD and ADC commands are used, as well as INC. The ADD command is used with the syntax:
ADD Tujuan, Asal
Assembly Programming Addition Operation
This ADD command will add values to Destination and Origin. The result obtained will be placed in Destination, in pascal language it is the same as the instruction Destination:=Destination + Origin. For example:
MOV AH,15h ; AH:=15h
MOV AL,4 ; AL:=4
ADD AH,AL ; AH:=AH+AL, jadi AH=19h
You need to note that in this ADD command, the Destination and Origin must have the same capacity, for example the registers AH (8 bits) and AL (8 bits), AX (16 bits) and BX (16 bits).
Some may wonder what will happen if the Destination where the sum result is stored is insufficient, such as adding 1234h to F221h.
ADD Concept
In the addition above, it can be seen that the addition of the number 1234 with F221 will produce the value 10455. To make it clearer, you can see that the binary addition produces the 17th bit, even though the register consists of only 16 bits. Such an addition operation will make the carry flag one, Example:
MOV AX,1234h ; NIlai AX:=1234h dan carry=0
MOV BX,0F221h ; Nilai BX:=F221h dan carry=0
ADD AX,BX ; Nilai AX menjadi 0455h dan carry=1
2. ADC
The ADC command is used in the same way as the ADD command, namely:
ADC Tujuan, Asal
The difference in this ADC command is that the Destination is the place to store the result of the addition of Destination and Origin plus the carry flag (Destination:=Destination+Origin+Carry). Such addition can solve problems such as those we have mentioned, such as the addition of the number 12345678h+9ABCDEF0h.
As we know that one register can only accommodate 16 bits, so for additions like the one above, you can use the ADC command to solve it, for example:
MOV AX,1234h ; AX = 1234h CF = 0
MOV BX,9ABCh ; BX = 9ABCh CF = 0
MOV CX,5678h ; BX = 5678h CF = 0
MOV DX,0DEF0h ; DX = DEF0h CF = 0
ADD CX,DX ; CX = 3568h CF = 1
ADC AX,BX ; AX = AX+BX+CF = ACF1
The sum result will be stored in the AX:CX register, namely ACF13568h. The flags affected by the ADD and ADC commands are CF, PF, AF, ZF, SF and OF.
3. INC
The INC(Increment) command is used specifically for incrementing by 1. The INC command only uses 1 byte of memory, while the ADD and ADC commands use 3 bytes. Therefore, if you want to perform an increment operation by 1, use the INC command. The syntax for using it is:
INC Tujuan
The value of the destination will be added by 1, like the command Goal:=Goal+1 in Turbo Pascal. The destination here can be a register or memory. Example: the INC AL command will add the value in the AL register by 1. The flags affected by this command are OF, SF, ZF, AF and PF.
Addition & Debug Program
After what we have learned, let's now make it a program with all the examples that have been given.
Program 8.1. Addition operation
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
; PROGRAM : TAMBAH.ASM ;
; FUNGSI : MELIHAT PENAMBAHAN ;
; YANG DILAKUKAN ;
; OLEH BERBAGAI ;
; PERINTAH ;
;===========================S'to=;
.MODEL SMALL
.CODE
ORG 100h
Proses :
MOV AH,15h ; AH:=15h
MOV AL,4 ; AL:=4
ADD AH,AL ; AH:=AH+AL, jadi AH=19h
MOV AX,1234h ; NIlai AX:=1234h dan carry=0
MOV BX,0F221h ; Nilai BX:=F221h dan carry=0
ADD AX,BX ; AX:=AX+BX, jadi nilai AX=0455h
MOV AX,1234h ; AX = 1234h CF = 0
MOV BX,9ABCh ; BX = 9ABCh CF = 0
MOV CX,5678h ; BX = 5678h CF = 0
MOV DX,0DEF0h ; DX = DEF0h CF = 0
ADD CX,DX ; CX = 3568h CF = 1
ADC AX,BX ; AX = AX+BX+CF = ACF1
INC AL ; AL:=AL+1, nilai pada AL ditambah 1
INT 20h
END Proses
After you finish typing the program 8.1., make it a COM program with tasm and tlink/t. After that try to see the truth of what has been given by using debug. First type:
C:\>debug Tambah.com
-r < tekan enter >
AX=0000 BX=0000 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0100 NV UP EI PL NZ NA PO NC
3597:0100 B415 MOV AH,15
-t < tekan enter >
The emphasis of "r" when first used to see the value of all registers. In the first line you can see the registers called general purpose (AX, BX, CX and DX). The SP register used in stack operations shows the value FFFE (end of Segment), so the stack operation will later be placed in that position.
On the second line you can see the four segment registers, namely DS, ES, SS and CS. The four segment registers show the same value, namely 3597 (may be different on your computer). This is because our program is a com program that only uses 1 segment. On the second line you can also see the IP register with a value of 100h. The IP register shows that we are currently at offset 100h from the active segment (CS:IP or 3597:100).
In the third line you can see 3597:0100, this value shows the pair of CS:IP. After that you can see the value of B415 which shows the contents of the address 3597:0100 is B4 while the contents of the address 3597:1001 is 15. This B415 value is actually a machine language for the MOV AH,15 instruction. So the machine language for the command "MOV AH,value" is B4 accompanied by the value. From this B415 value it can be seen that the MOV command will use 2 bytes in memory.
After that press 't' to execute the instruction contained in the address shown CS:IP(MOV AH,15). After you press 't' the result will be displayed after the instruction "MOV AH,15" is executed:
AX=1500 BX=0000 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0102 NV UP EI PL NZ NA PO NC
3597:0102 B004 MOV AL,04
-t < enter >
It can be seen that the value of AX changes from 0000 to 1500 after receiving the MOV AH,15 command. Press 't' followed by enter to see the changes in the values of the respective registers.
AX=1504 BX=0000 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0104 NV UP EI PL NZ NA PO NC
3597:0104 02E0 ADD AH,AL
-t < enter >
AX=1904 BX=0000 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0106 NV UP EI PL NZ NA PO NC
3597:0106 B83412 MOV AX,1234
-t < enter >
AX=1234 BX=0000 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0109 NV UP EI PL NZ NA PO NC
3597:0109 BB21F2 MOV BX,F221
-t < enter >
AX=1234 BX=F221 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=010C NV UP EI PL NZ NA PO NC
3597:010C 03C3 ADD AX,BX
-t < enter >
AX=0455 BX=F221 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=010E NV UP EI PL NZ NA PE CY
3597:010E B83412 MOV AX,1234
-t < enter >
AX=1234 BX=F221 CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0111 NV UP EI PL NZ NA PE CY
3597:0111 BBBC9A MOV BX,9ABC
-t < enter >
AX=1234 BX=9ABC CX=0030 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0114 NV UP EI PL NZ NA PE CY
3597:0114 B97856 MOV CX,5678
-t < enter >
AX=1234 BX=9ABC CX=5678 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0117 NV UP EI PL NZ NA PE CY
3597:0117 BAF0DE MOV DX,DEF0
-t < enter >
AX=1234 BX=9ABC CX=5678 DX=DEF0 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=011A NV UP EI PL NZ NA PE CY
3597:011A 03CA ADD CX,DX
-t < enter >
AX=1234 BX=9ABC CX=3568 DX=DEF0 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=011C NV UP EI PL NZ NA PO CY
3597:011C 13C3 ADC AX,BX
-t < enter >
AX=ACF1 BX=9ABC CX=3568 DX=DEF0 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=011E NV UP EI NG NZ AC PO NC
3597:011E FEC0 INC AL
-t < enter >
AX=ACF2 BX=9ABC CX=3568 DX=DEF0 SP=FFFE BP=0000 SI=0000 DI=0000
DS=3597 ES=3597 SS=3597 CS=3597 IP=0120 NV UP EI NG NZ NA PO NC
3597:0120 CD20 INT 20
-Q < enter >
Typing "Q" indicates that we want to exit the debug environment and will return to a:>.
Assembly Programming Subtraction Operation
1. SUB
For subtraction operations, you can use the SUB command with the syntax:
SUB Tujuan, Asal
Assembly Programming Reduction Operation
The SUB command will subtract the value in Destination from the Origin. The result obtained will be placed in Destination, in Pascal language it is the same as the instruction Destination:=Destination-Origin. Example:
MOV AX,15 ; AX:=15
MOV BX,12 ; BX:=12
SUB AX,BX ; AX:=15-12=3
SUB AX,AX ; AX=0
To zero a register you can subtract it from itself like SUB AX,AX.
2. SBB
As in addition operations, in subtraction operations with large numbers (more than 16 bits), you can use the SUB command accompanied by SBB (Substract With Carry). The SBB command is used with the syntax:
SBB Tujuan, Asal
The SBB command will subtract the Destination value from the Origin in the same way as the SUB command, then the result obtained is subtracted again with the Carry Flag(Destination:=Destination-Origin-CF).
Program 8.2. Reducing the number that causes Borrow
; PROGRAM : KURANG.ASM ;
; AUTHOR : S'to ;
; FUNGSI : MENGURANGKAN ANGKA ;
; 122EFFF-0FEFFFF ;
; ;
;================================;
.MODEL SMALL
.CODE
ORG 100h
TData :
JMP Proses ; Lompat ke Proses
ALo EQU 0EFFFh
AHi EQU 122h
BLo EQU 0FFFFh
Bhi EQU 0FEh
HslLo DW ?
HslHi DW ?
Proses :
MOV AX,ALo ; AX=EFFFh
SUB AX,Blo ; Kurangkan EFFF-FFFF, jadi AX=F000
MOV HslLO,AX ; HslLo bernilai F000
MOV AX,AHi ; AX=122h
SBB AX,BHi ; Kurangkan 122-FE-Carry, AX=0023
MOV HslHi,AX ; HslHi bernilai 0023
INT 20h ; Kembali ke DOS
END TData
Here we can see how to define a constant value (a value that cannot be changed) and a variable with:
ALo EQU 0EFFFh
AHi EQU 122h
BLo EQU 0FFFFh
Bhi EQU 0FEh
HslLo DW ?
HslHi DW ?
The EQU command is used to define something constant, data that has been defined with the EQU command cannot be changed. With the EQU command we define that ALo = 0EFFF, AHi = 122, BLo = FFFF and BHi = 0FE. To accommodate the results of the subtraction AB (122EFFF-FEFFF) later, we define a place to store it with the names HslLo and HslHi.
The '?' sign is used to indicate that the place we ordered as much as 1 word (DW) is not given the initial data that will be contained in the variable (HslLo and HslHi). So the data that will be contained in HslLo and HslHi can be anything and we do not know it. We skip the place of our program data with the JMP command so that the computer does not execute the program data as a command.
MOV AX,ALo
SUB AX,Blo
MOV HslLO,AX
To subtract the number 122EFFF from 0FEFFFF we can subtract the low word from the number first, which is EFFF-FFFF. This is because the register capacity is only 16 bits. You can see that the subtraction of EFFF-FFFF will cause a borrow, the low word result (F000) obtained is then stored in the variable HslLo.
122 EFFF\
FE FFFF\
---------- -\
023 F000
Up to this point we have finished getting the value of the low word, which is stored in the variable HslLo.
MOV AX,AHi
SBB AX,BHi
MOV HslHi,AX
The next step is to calculate the high word, which is the subtraction of 122-FE-Carry using the SBB command, then the problem is easily solved. Finally, we will get the result of the subtraction of 122EFFF-0FEFFFF, which is 23F000 which is stored in the pair HslHi:HslLo(0023F000).
3. DEC
The DEC (Decrement) command is used specifically for reduction by 1. The DEC command only uses 1 byte of memory, while the SUB and SBB commands use 3 bytes. Therefore, if you want to perform a reduction operation by 1, use the DEC command. The syntax for using this dec command is:
DEC Tujuan
The value at the destination will be reduced by 1, like the command Destination:=Destination-1 in Turbo Pascal. The destination here can be a register or memory. For example: the command DEC AL will reduce the value in the AL register by 1.
Program 8.3. Mencetak karakter "Z".."A"
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
; PROGRAM : CBA0.ASM ;
; FUNGSI : MENCETAK KARAKTER ;
; "Z".."A" DENGAN ;
; INT 21h SERVIS 02 ;
;==========================S'to=;
.MODEL SMALL
.CODE
ORG 100h
Proses :
MOV AH,02h ; Nilai servis
MOV DL,'Z' ; DL=5Ah
MOV CX,26 ; Banyaknya pengulangan yang akan
; dilakukan
Ulang:
INT 21h ; Cetak karakter !!
DEC DL ; Kurang DL dengan 1
LOOP Ulang ; Lompat ke Ulang
INT 20h
END Proses
Program 8.3. when run will print the characters "Z" to "A" as follows:
ZYXWVUTSRQPONMLKJIHGFEDCBA
Assembly Programming Multiplication Operation
For multiplication, you can use the MUL command with the syntax:
MUL Sumber
Assembly Programming Multiplication Operations
The source here can be an 8-bit register (eg: BL, BH,..), a 16-bit register (eg: BX, DX,..) or a variable. There are 2 possibilities that will occur in this MUL command according to the type of 8-bit or 16-bit multiplication.
If the Source is 8 bits such as MUL BH then the computer will take the value in BH and the value in AL to multiply. The result obtained will always be stored in the AX register. If the source is 16 bits such as MUL BX then the computer will take the value in BX and the value in AX to multiply. The result obtained will be stored in the DX and AX registers (DX:AX), so the DX register stores the high word and AX stores the low word.
Program 8.4. Multiplication process with MUL
;================================;
; PROGRAM : KALI.ASM ;
; AUTHOR : S'to ;
; FUNGSI : MENGALIKAN BILANGAN;
; 16 BIT, HASIL ;
; PADA DX:AX ;
;================================;
.MODEL SMALL
.CODE
ORG 100h
TData :
JMP Proses ; Lompat ke Proses
A DW 01EFh
B DW 02FEh
HslLo DW ?
HslHi DW ?
Proses:
MOV AX,A ; AX=1EF
MUL B ; Kalikan 1FH*2FE
MOV HslLo,AX ; AX bernilai C922 sehingga HslLo=C922
MOV HslHi,DX ; DX bernilai 0005 sehingga HslHi=0005
INT 20h ; Kembali ke DOS
END TData
In program 8.4. we define the numbers for variables 'A'=1EF and 'B'=2FE with DW. Since EQU is not used, the variables 'A' and 'B' can be changed if desired.
Assembly Programming Division Operation
The division operation is basically the same as multiplication. For the division operation, the DIV command is used with the syntax:
DIV Sumber
Assembly Programming Division Operations
If the source is an 8-bit operand such as DIV BH, then the computer will take the value in the AX register and divide it by the value of BH. The result of this 8-bit division will be stored in the AL register and the remainder of the division will be stored in the AH register.
If the source is a 16-bit operand such as DIV BX, then the computer will take the value in the DX:AX register and divide it by the value of BX. The 16-bit result of this division will be stored in the AX register and the remainder of the division will be stored in the DX register.
Program 8.5. Process of dividing 16 bit numbers
;================================;
; PROGRAM : BAGI.ASM ;
; AUTHOR : S'to ;
; FUNGSI : MEMBAGI BILANGAN ;
; 16 BIT, HASIL ;
; PADA DX:AX ;
;================================;
.MODEL SMALL
.CODE
ORG 100h
TData :
JMP Proses ; Lompat ke Proses
A DW 01EFh
B DW 2
Hsl DW ?
Sisa DW ?
Proses:
SUB DX,DX ; Jadikan DX=0
MOV AX,A ; AX=1EF
DIV B ; Bagi 1EF:2
MOV Hsl,AX ; AX bernilai 00F7 sehingga Hsl=00F7
MOV Sisa,DX ; DX berisi 0001 sehingga Sisa=0001
INT 20h ; Kembali ke DOS
END Tdata
Try tracing with debug to see the results obtained on the AX and DX registers.
Assembly Programming Pointer Operations
In the previous programs (subtraction, multiplication and division) you can see that the results of arithmetic operations are stored in 2 variables where 1 variable is to hold the results of the high word and 1 word is to hold the low word. Doesn't this seem strange, because if we want to see the value then the value must be united before it can be read. Is there another way so that the results can be stored in one variable only? YES !!, but for that you must use a pointer to access it. If you do not use a pointer then the data type of the container must match the register. Without a pointer to move data from a variable to an 8-bit register, then the variable must also be 8 bits which can be defined with DB, likewise for a 16-bit register with a variable defined with DW. Example:
A DB 17 ; DB=8 bit jadi A=8 bit
B DW 35 ; DW=16 bit jadi B=16 bit
MOV AL,A ; 8 bit dengan 8 bit
MOV AX,B ; 16 bit dengan 16 bit
Getting to Know Assembly Programming Pointers
As in the example above, you cannot use the MOV AX,A command because both operands do not have the same capacity (16 and 8 bits). If you move data from operands with different data types, the message " Error BAGI.ASM(20) Operand types do not match" will be displayed. By using pointers, this is not a problem. Before that, let's first look at the various data types found in assembler.
1. Data Type
In assembler we can store data with various different data types. We can give a name to the data, to make it easier to access the data. The data types contained in assembler can be seen in Figure 9.1.
Figure 9.1. Various Data Types
------------------------------------------
NAMA UKURAN
DB<Define Byte> 1 BYTE
------------------------------------------
DW<Define Word> 2 BYTE
DD<Define DoubleWord> 4 BYTE
DF<Define FarWords> 6 BYTE
DQ<Define QuadWord> 8 BYTE
DT<Define TenBytes> 10 BYTE
-------------------------------------------
For example, look at how the data type in Figure 9.1 is used:
.MODEL SMALL
.CODE
ORG 100h
TData :
JMP Proses
A DB 4 ; 1 byte, nilai awal='4'
B DB 4,4,4,2,? ; 1*5 byte, nilai awal=4,4,4,2,?
C DB 4 DUP(5) ; 1*4 byte, nilai awal='5'
D DB 'HAI !!' ; 6 byte berisi 6 karakter
E DW ? ; 1 word tidak diketahui isinya
F DW ?,?,? ; 3 word tidak diketahui isinya
G DW 10 DUP(?) ;10 word tidak diketahui isinya
H DD ? ; 1 DoubleWord tanpa nilai awal
I DF ?,? ; 2 FarWord tanpa nilai awal
J DQ 0A12h ; 1 QuadWord, nilai awal='0A12'
K DT 25*80 ; 1 TenBytes, nilai awal='2000'
L EQU 666 ; Konstanta, L=666
M DB '123' ; String '123'
N DB '1','2','3' ; String '123'
O DB 49,50,51 ; String '123'
Proses : ;
END Tdata
In the first line ("A DB 4") we define one byte for a variable named "A", this variable is given the value "4".
In the second line ("B DB 4,4,4,2,?") we define 5 bytes in pairs for a variable named "B". The first three bytes in the variable "B" are all given an initial value of "4", the fourth byte is given an initial value of 2 while the fifth byte is not given an initial value.
In the third line ("C DB 4 DUP(5)") we define as many as 4 bytes of data which are given the initial value "5" all (DUP=Duplication). So with the DUP command we can define an Array.
In the fourth line ("D DB 'HAI !! '") we define a string with DB. To define the next string we will always use the DB data type. If we define a string with DW then only 2 characters can be entered, the placement format in memory will later reverse the number.
In the fifth line ("E DW ?") we define a Word data type that is not given an initial value. The value contained in the variable "E" can be anything, we don't care.
In the twelfth line ("L EQU 666") we define a constant for the variable "L", so the value of "L" cannot be changed.
In the variables M, N, O we define a string "123" in different forms. All three will be stored by the assembler in the same form, as the numbers 49, 50 and 51.
In the following programs you will see that we always skip the data area ("TData:JMP Process"), why is that? If we do not skip this data area then the process will go through this data area. Program data will be considered by the computer as an instruction to be executed so anything can happen there. For example we will create a program that does not skip the data area, so the data will be executed as an instruction. This program has been set up in such a way as to sound your speaker, at the end the data is given the value CD20 which is the machine language of the INT 20h instruction.
Program 9.1. Programs That Execute Data Areas
;=====================================;
; PROGRAM : BHSMESIN.ASM ;
; AUTHOR : S'to ;
; FUNGSI : MEMBUNYIKAN SPEAKER ;
; DENGAN DATA PROGRAM ;
; ;
;======================================
.MODEL SMALL
.CODE
ORG 100h
Tdata:DB 0E4h,61h,24h,0FEh,0E6h,61h,0B9h,0D0h,7h,0BBh,9Ah
DB 2h,8Bh,0D1h,51h,34h,2h,0E6h,61h,0D1h,0C3h,73h,6h
DB 83h,0C1h,0h,0EBh,0Bh,90h,52h,2Bh,0D1h,87h,0D1h,5Ah
DB 81h,0C1h,34h,8h,0E2h,0FEh,59h,0E2h,0E2h,0CDh,20h
END Tdata
2. Data Storage in Memory
Before we go any further, let's first see how a computer stores a value in memory. To do this, type the program 9.2. which only defines the data.
Program 9.2. Defining Data
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
A DB 12h,34h
B DW 0ABCDh
C DD 56789018h
D DB 40 DUP(1)
END Tdata
After the program 9.2. is typed and made into COM with TASM.EXE and TLINK.EXE, use debug to see how the data is stored in the computer's memory.
Figure 9.2. Program data 9.2
C:\>debug data.com A B C D
-d +-+-+ +-+-+ +----+----+ +----+--------
3001:0100 EB 31 90 12 34 CD AB 18-90 78 56 01 01 01 01 01
3001:0110 01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01
3001:0120 01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01
3001:0130 01 01 01 E0 AC 91 51 AD-8B C8 25 0F 00 8B D9 B1
3001:0140 04 D3 EB D1 E3 26 03 1E-64 01 8B 17 06 1F BF 04
3001:0150 00 57 BF FA 05 E8 83 0A-73 03 E8 63 0A 26 89 15
3001:0160 B9 FF FF EB 18 8E 06 82-01 2B DB 26 02 1C 7D 09
3001:0170 46 80 EB 80 8A FB 26 8A-1C 46 E8 16 DA 48 7D E5
-q
The first three bytes in Figure 9.1 are the machine language of the "JUMP PROCESS" and "NOP" commands. The 4th and 5th bytes are the data of the variable "A", we can see that the data of the variable "A" (1234) defined by "DB" is stored in the computer's memory as defined.
The next two bytes (bytes 6 and 7), are data from variable C that we have defined with "DW (2 bytes)". It turns out that the two bytes of variable "C" (ABCD) are stored in memory in reverse order (CDAB)!. Why is that? This is because the storage in memory stores its high value at a high address. You can see in the next 4 bytes, namely data from variable "D" is also stored in reverse order (56789018 becomes 18907856).
3. Using Pointers
Now we are ready to see how to move data from variables or registers of different data types, using pointers. To do this, use the PTR command with the writing format:
TipeData PTR operand
To be clearer, let's look at its use in the program.
Program 9.3. Using Pointers
;=================================;
; PROGRAM : PTR.ASM ;
; AUTHOR : S'to ;
; FUNGSI : MEMINDAHKAN DATA ;
; ANTAR TIPE DATA YANG;
; BERBEDA !!! ;
;=================================;
.MODEL SMALL
.CODE
ORG 100h
TData :
JMP Proses ; Lompat ke Proses
A DW 01EFh ; 2 Byte
B DW 02FEh ; 2 Byte
D DD ? ; 4 Byte
Proses:
MOV AL,BYTE PTR A ; AL=EF, AX=?EF
MOV AH,BYTE PTR A+1 ; AH=01, AX=01EF
MOV BX,B ; BX=02FE
MOV WORD PTR D,AX ; D=??01EF
MOV WORD PTR D+2,BX ; D=02FE01EF
INT 20h ; Kembali ke DOS
END TData
At the beginning we define variables "A" and "B" with data type word (16 bit) which have initial values 01EF and 02FE, and variable "C" with data type DoubleWord (32 bit) which is not initialized.
MOV AL,BYTE PTR A
MOV AH,BYTE PTR A+1
In both commands, we move data from variable "A" to register AX byte by byte. Note that we must adjust the data transfer to its capacity. Therefore, "BYTE" PTR is used to move 1 byte of data to an 8-bit register, thus to move 16-bit data, "WORD" PTR must be used. In the first line, we move the low byte of variable "A" (EF) to register AL, then in the second line we move its high byte (01) to register AH. Note that we use "BYTE PTR A" for the low byte value and "BYTE PTR+1" for the high byte of variable "A" because data storage in computer memory stores the high byte first (See section 9.3.).
MOV BX,B
MOV WORD PTR D,AX
MOV WORD PTR D+2,BX
In this section we will try to move data from 2 16 bit registers to 1 32 bit variable. In the first line "MOV BX,B" of course there is no problem because both operands have the same capacity. In the second line "MOV WORD PTR D,AX" we move the value in the AX register to be stored in the "D" variable as the low word. Then in the third line "MOV WORD PTR D+2,BX" we enter the value from the BX register in the "D" variable for the high word so that the current value is BX:AX=02FE01EF. Note that in the third line we skip 2 bytes (WORD PTR+2) from the "D" variable to store the high word.
Now by using this pointer we can store the result of 16 bit multiplication in 1 32 bit variable. For that see program 9.4.
Program 9.4. Storing the values of 2 registers in 1 variable
;================================;
; PROGRAM : KALIPTR.ASM ;
; AUTHOR : S'to ;
; FUNGSI : MENGALIKAN BILANGAN;
; 16 BIT, HASIL ;
; PADA DX:AX ;
;================================;
.MODEL SMALL
.CODE
ORG 100h
TData :
JMP Proses ; Lompat ke Proses
A DW 01EFh ; 2 Byte
B DW 02FEh ; 2 Byte
Hsl DD ? ; 4 Byte
Proses:
MOV AX,A ; AX=1EF
MUL B ; Kalikan 1FH*2FE
MOV WORD PTR Hsl,AX ; AX bernilai C922, Hsl=??C922
MOV WORD PTR Hsl+2,DX ; DX bernilai 0005, Hsl=0005C922
INT 20h ; Kembali ke DOS
END TData
Hope this is useful & happy learning!
Program Assembly ON-OFF LED
Assembly Program Turning LED On - Off
Part 1
;- BAB4_01.ASM -------------------------------------------------------------------
;
; Program menyalakan/mematikan LED selama 1 detik
;
; --------------------------------------------------------------------------------
;
RATUSAN EQU 100 ; 100 x 10000 ud = 1 detik
CACAH EQU -10000
ORG 0H
MOV TMOD,#01H ; gunakan timer 0 mode 16 bit (0000 0001)
MULAI:
MOV P1,#00H ; hidupkan LED selama 1 detik
CALL TUNDA
MOV P1,#0FFH ; matikan LED selama 1 detik
CALL TUNDA
SJMP MULAI ; ulangi lagi dari awal
TUNDA: MOV R1,#RATUSAN
LAGI: MOV TH0,#HIGH CACAH ; isi TH0 dengan HIGH(CACAH)
MOV TL0,#LOW CACAH ; isi TL0 dengan LOW(CACAH)
SETB TR0 ; hidupkan timer 0
TUNGGU: JNB TF0,TUNGGU ; tunggu hingga melimpah
CLR TF0 ; matikan flag limpahan timer 0 scr manual
CLR TR0 ; matikan timer 0
DJNZ R1,LAGI ; apakah sudah #ratusan kali?
; BELUM! ulangi dari LAGI
RET ; SUDAH! kembali dari subrutin TUNDA
END
Part 2
;- BAB4_02.ASM -------------------------------------------------------------------
;
; Program menyalakan/mematikan LED setelah penekanan tombol
; pada P1.4 sebanyak 5 kali dengan menggunakan timer
;
; --------------------------------------------------------------------------------
;
CACAH EQU -5 ; cacah sama dengan 5
ORG 0H
;
MOV TMOD,#0Eh ; gunakan timer 0 mode 8 bit isi-ulang otomatis
LAGI: MOV TH0,#CACAH ; isi TH0 dengan #cacah
MOV TL0,#CACAH ; isi TL0 dengan #cacah
SETB TR0 ; aktifkan timer0
CEK: JNB TF0,$ ; tunggu hingga melimpah
CLR P1.0 ; hidupkan P1.0 setelah 5 kali
; penekanan tombol pada T0 (P1.4)
CLR TF0 ; bersihkan flag limpahan timer 0 scr manual
CEK1: JNB TF0,$ ; tunggu hingga overflow
SETB P1.0 ; matikan P1.0 setelah 5 kali
; penekanan tombol pada T0 (P1.4)
CLR TF0 ; bersihkan flag limpahan timer 0 scr manual
SJMP CEK ; ulangi lagi dari awal
END
Hope this is useful & happy learning!
Assembly Program Sounds 500Hz Frequency Speaker
Assembly Program Sounds 500Hz Frequency Speaker
;- BAB4_03.ASM -------------------------------------------------------------------
;
; Program membunyikan speaker dengan menggunakan frekuensi 500Hz
;
; --------------------------------------------------------------------------------
;
ASIK EQU -1000 ; nilai isi ulang 1000
ORG 0H
;
MOV TMOD,#01H ; menggunakan timer 0 mode 16 bit (0000 0001)
KALANG: MOV TH0,#HIGH ASIK ; siapkan nilai isi ulang pada
MOV TL0,#LOW ASIK ; TH0 dan TL0 (timer 0)
SETB TR0 ; hidupkan timer 0
TUNGGU: JNB TF0, TUNGGU ; tunggu hingga melimpah
CLR TR0 ; hentikan timer 0
CLR TF0 ; nol-kan flag overflow
CPL P1.0 ; 'toggle' pada P1.0
SJMP KALANG ; ulangi lagi dari awal
END
Hope this is useful & happy learning!
Alarm Assembly Program with LED Flip-Flop
Alarm Assembly Program With Flip-Flop Lamp
Alarm Schematic With Flip-Flop Lamp
Part 1
;- BAB4_04.ASM -------------------------------------------------------------------
;
; Alarm dan lampu flip-flop dengan Selang waktu menggunakan interupsi timer 1
; Speaker dipasang pada P1.0 sedangkan
; Lampu flip-flop (LED) dipasang pada Port 0 bit 1,2,4 dan 5
;
;---------------------------------------------------------------------------------
Org 0h
;
ljmp Mulai
org 1Bh ; alamat untuk interupsi timer 1
ljmp timer_1 ; karena subrutin ini panjang pindahkan
; ke lain tempat dengan LJMP
;--------------------------------------------------------------------------------
; sub rutin delay pendek DELAY
;--------------------------------------------------------------------------------
Delay: Mov R6,#0
Delay1: Nop ; 1 siklus
Djnz R6,Delay1 ; 2 siklus
Ret
;
;--------------------------------------------------------------------------------
; sub rutin delay panjang LDELAY
;--------------------------------------------------------------------------------
ldelay:
Mov R7,#0
ld1: acall delay
acall delay
acall delay
Djnz R7,ld1 ; ulangi sebanyak 256x
Ret
;
; --------------------------------------------------------------------------------
; subrutin interupsi timer 1
; Penghasil pulsa pada Port 1 bit ke 0
; --------------------------------------------------------------------------------
timer_1:
clr TR1 ; Hentikan Timer 1
cjne R0,#0,Tone1 ; apakah status keluaran (R0) = low
setb P1.0 ; YA! buat P1.0 berlogika 1
mov R0,#1 ; ubah status keluaran -> high
sjmp Tone2 ; bunyikan nada 750/500 Hz
Tone1:
clr P1.0 ; TIDAK! buat P1.0 berlogika 0
mov R0,#0 ; ubah status keluaran -> low
;
Tone2:
cjne R1,#0,Tone3 ; apakah pola penyalaan mode-1?
mov TL1,#LOW (-655) ;YA! Tone 750 Hz = pulsa per 655 ud
mov TH1,#HIGH (-655)
sjmp Tone4
Tone3:
mov TL1,#LOW (-1000) ;TIDAK! Tone 500 Hz = pulsa per 1000 ud
mov TH1,#HIGH (-1000)
Tone4:
setb TR1 ; hidupkan Timer-1
reti
; --------------------------------------------------------------------------------
; Awal dari program
; --------------------------------------------------------------------------------
Mulai:
clr A ; nolkan akumulator
mov IE,A ; matikan semua interupsi
setb IE.7 ; aktifkan semua interupsi
setb IE.3 ; aktifkan interupsi timer 1
mov TCON,A ; bersihkan TCON
mov TMOD,#11h ; mode timer 16 bit
setb TR1 ; jalankan timer 1
;
tunggu:
mov R1,#0 ; R1 sebagai tanda untuk tone 750 Hz
setb P1.6
setb P1.7
clr P1.4
clr P1.5
lcall ldelay
mov R1,#1 ; R1 sebagai tanda untuk tone 500 Hz
setb P1.4
setb P1.5
clr P1.6
clr P1.7
lcall ldelay
sjmp tunggu ; ulangi terus menerus
;
End
Part 2
;- BAB6_01.ASM -------------------------------------------------------------------
;
; Aplikasi sistem alarm yang diaktifkan melalui interupsi
; JIka dideteksi INT0 (1 ke 0) akan menghasilkan alarm 400 Hz selama 1 detik
;
;---------------------------------------------------------------------------------
ORG 0H
;
LJMP UTAMA ; ke program utama
LJMP EX0RLI ; ke layanan interupsi INT0
ORG 0BH
LJMP T0RLI ; vektor interupsi timer 0
ORG 1BH
LJMP T1RLI ; vektor interupsi timer 1
;---------------------------------------------------------------------------------
; program utama
;
ORG 30H
UTAMA: SETB IT0 ; interupsi pemicu sisi negatif (1 ke 0)
MOV TMOD,#11H ; mode pewaktu timer 0 dan 1 16-bit
MOV IE,#81H ; aktifkan INT0 saja
SJMP $ ; kalang forever...
;---------------------------------------------------------------------------------
; rutin layanan interupsi eksternal 0
;
EX0RLI:
MOV R7,#20 ; 20 x 50000 ud = 1 detik
SETB TF0 ; paksa terjadi interupsi timer 0
SETB TF1 ; paksa terjadi interupsi timer 1
SETB ET0 ; aktifkan interupsi timer 0
SETB ET1 ; dan timer 1
RETI
;---------------------------------------------------------------------------------
; rutin layanan interupsi timer 0
;
T0RLI:
CLR TR0 ; hentikan timer 0
DJNZ R7,LAGI ; apakah sudah 20 kali pengulangan?
CLR ET0 ; YA! matikan interupsi timer 0
CLR ET1 ; dan timer 1
LJMP SELESAI ; selesai
LAGI: MOV TH0,#HIGH (-50000) ; TIDAK! isi kembali dengan data awal
MOV TL1,#LOW (-50000) ; pencacahan (-500000)
SETB TR0 ; hidupkan timer 0
SELESAI:
CLR P1.0 ; matikan alarm
RETI
;---------------------------------------------------------------------------------
; rutin layanan interupsi timer 1
;
T1RLI: CLR TR1 ; hentikan timer 1
MOV TH1,#HIGH (-1250) ; isi kembali dengan data awal nada
MOV TL1,#LOW (-1250) ; sebesar -1250
CPL P1.0 ; lakukan komplemen P1.0
SETB TR1 ; hidupkan timer 1
RETI
;
END
Hope this is useful & happy learning!
Assembly Program to Read Keyboard Characters
Assembly Program to Read Keyboard Key Characters
Part 1
;- BAB5_01.ASM -------------------------------------------------------------------
;
; semuanya menggunakan interupsi, tidak ada program utama, kecuali
; inisialiasi baud rate dan interupsi
; Program akan menerima karakter (huruf), kemudian mengirimkannya kembali
; ke pengirim berupa huruf besar (kode ASCII - 32)
; Kristal digunakan 11.0592 MHz
;
;---------------------------------------------------------------------------------
ORG 00H
;
SJMP MAIN ; lompat ke program utama
;---------------------------------------------------------------------------------
; isi vektor interupsi port serial dengan RLI
;
ORG 23H ; lokasi vektor interupsi port serial
SJMP SERINT ; karena panjang lompat ke SERINT
;---------------------------------------------------------------------------------
;
ORG 030H ; program utama mulai di sini
MAIN: MOV TMOD,#20H ; timer 1 mode 2 (8-bit, isi-ulang otomatis)
MOV TH1,#0F4H ; 2400 baud rate
MOV SCON,#50H ; Mode serial 8-bit UART
SETB TR1 ; Jalankan Timer 1
MOV R0,#60H ; penunjuk tampilan
MOV SP,#10H ; definisikan lokasi stack
;---------------------------------------------------------------------------------
; inisialisasi interupsi
;
SETB ES
SETB EA
;---------------------------------------------------------------------------------
; interupsi sekarang aktif
;
DEAD: SJMP DEAD ; perulangan terus menerus
;---------------------------------------------------------------------------------
; penanganan interupsi
; saat pengguna menekan suatu tombol di komputer, program terminal akan
; mengirimkan karakter tombol tsb. ke mcs-51 melalui kanal serial
;---------------------------------------------------------------------------------
SERINT:
; periksa apa yang menyebabkan interupsi
;
JB RI,RCV_ch ; apakah RI=1 (data diterima)?
; YA! ada karakter di SBUF lompat ke RCV_ch
CLR TI ; TIDAK! hapus TI
RETI ; abaikan interupsi pengiriman
;---------------------------------------------------------------------------------
; penanganan interupsi penerimaan
;---------------------------------------------------------------------------------
RCV_ch: PUSH PSW ; simpan register-register penting (ACC dan PSW)
PUSH ACC
MOV A,SBUF ; baca karakter yang diterima
CLR RI ; kosongkan RI (agar bisa terima data lagi)
;
MOV @R0,A ; simpan karakter di RAM
INC R0
CLR C
SUBB A,#32 ; konversi ke huruf besar (ASCII-32)
MOV SBUF,A ; kirimkan kembali
;
EXIT: POP ACC ; ambil ACC kembali (dari stack)
POP PSW ; dan juga PSW
RETI
END
Part 2
;- BAB5_02.ASM -------------------------------------------------------------------
;
; semuanya menggunakan interupsi, tidak ada program utama, kecuali
; inisialiasi baud rate dan interupsi
; Program akan menerima karakter (huruf), kemudian memeriksanya, jika
; isinya 'a' --> lampu LED 1,3,5 dan 7 menyala
; isinya 'b' --> lampu LED 0,2,4 dan 6 menyala
; isinya 's' --> mematikan semua LED
; isi selain di atas -> LED hidup semua!
; Kristalnya 11.0592 MHz
;
;---------------------------------------------------------------------------------
ORG 00H
SJMP MAIN ; lompat ke program utama
;---------------------------------------------------------------------------------
; isi vektor interupsi port serial dengan RLI
;
ORG 23H ; lokasi vektor interupsi port serial
SJMP SERINT ; karena panjang lompat ke SERINT
;---------------------------------------------------------------------------------
;
ORG 030H ; program utama mulai di sini
MAIN: MOV TMOD,#20H ; timer 1 mode 2 (8-bit, isi-ulang)
MOV TH1,#0FDH ; 9600 baud rate
MOV SCON,#50H ; Mode serial: 8-bit UART
SETB TR1 ; Jalankan Timer 1
MOV R0,#60H ; penunjuk tampilan
MOV SP,#10H ; definisikan lokasi stack
;---------------------------------------------------------------------------------
; inisialisasi interupsi agar aktif
;
SETB ES
SETB EA
;---------------------------------------------------------------------------------
; sekarang kirimkan kalimat 'Selamat datang...'
;
MOV DPTR,#DATANYA ; DPTR menunjuk awal data
MOV R2,#20 ; ada 20 karakter (termasuk ascii 13 dan 10)
KIRIM: CLR A ; kosongkan akumulator
MOVC A,@A+DPTR ; baca karakter
MOV SBUF,A ; kirimkan
JNB TI,$ ; tunggu hingga selesai kirim
CLR TI ; nol-kan TI
INC DPTR ; karakter berikutnya
DJNZ R2,KIRIM
DEAD: SJMP DEAD ; perulangan terus menerus
;---------------------------------------------------------------------------------
; penanganan interupsi
; saat pengguna menekan tombol di komputer program terminal akan
; mengirimkan karakter tombol ybs. ke mcs-51
;
SERINT:
; apa yang menyebabkan interupsi
;
JB RI,RCV_ch ; apakah RI=1 (set, data diterima)?
; YA! ada karakter di SBUF
CLR TI ; TIDAK! hapus TI
RETI ; abaikan interupsi pengiriman
;---------------------------------------------------------------------------------
; penanganan interupsi penerimaan
;
RCV_ch: PUSH PSW ; simpan register-register
PUSH ACC
MOV A,SBUF ; baca karakter yang diterima
CLR RI ; kosongkan RI (agar bisa terima lagi)
;
CJNE A,#'a',LED1 ; apakah diterima karakter 'a'?
MOV P1,#01010101B ; YA! hidupkan LED di P1 bit 1, 3, 5 dan 7
SJMP EXIT
LED1: CJNE A,#'b',LED2 ; TIDAK! Apakah diterima karakter 'b'?
MOV P1,#10101010B ; YA! hidupkan LED di P1 bit 0, 2, 4 dan 6
SJMP EXIT
LED2: CJNE A,#'s',LED3 ; TIDAK! Apakah diterima karakter 's'?
MOV P1,#11111111B ; YA! matikan semua LED
SJMP EXIT
LED3: MOV P1,#00000000B ; TIDAK! hidupkan semua LED
;
EXIT: MOV SBUF,A ; kirimkan kembali karakter yang diterima
;
POP ACC ; ambil ACC kembali (dari stack)
POP PSW ; dan juga PSW
RETI ; kembali ke ????
DATANYA:
DB 'Selamat datang...',13,10
END
Part 3
$mod51
waktu equ 75 ; inisialisasi waktu
mov b,#0
Mov P3,#191
mulai:
anl b,#0fh
mov a,b
Lcall tampil
mov p0,a
setb c
Lcall DELAY500MS
;delay: mov r0,#500
; mov r1,#500
;wait: djnz r0,wait
; djnz r1,wait
baca_tombol:
mov c,p3.2
jnc naik
mov c,p3.3
jnc turun
jmp baca_tombol
naik:
inc b
jmp mulai
turun:
dec b
jmp mulai
;---------------
; delay 500 ms
;---------------
DELAY500MS:
PUSH ACC
PUSH 00H
MOV A,#032H ; 500 milli second
X10MS: CALL DELAY10MS
DJNZ ACC,X10MS
POP 00H
POP ACC
RET
;-------------
; DELAY 10 ms
;-------------
DELAY10MS:
PUSH ACC
PUSH 00H
MOV 00H,#050H
D10MS1: MOV A,#0C8H
DJNZ ACC,$
DJNZ R0,D10MS1
POP 00H
POP ACC
RET
;*************************************
;* Mengubah nilai 0..9 di Accumulator *
;* menjadi kombinasi ruas tampilan *
;*************************************
tampil:
INC A ; Melompati instruksi RET
MOVC A,@A+PC ; Ambil isi Array KombinasiRuas
RET
; -gfedcba
DB 11000000B ; 0
DB 11111001B ; 1
DB 10100100B ; 2
DB 10110000B ; 3
DB 10011001B ; 4
DB 10010010B ; 5
DB 10000010B ; 6
DB 11111000B ; 7
DB 10000000B ; 8
DB 10010000B ; 9
DB 11111111B ; Blank
BlankDisplay:
DB 11111111B ; Blank
DB 11111111B ; Blank
DB 11000000B ; 0
DB 11000000B ; 0
end
Part 4
ORG 00H
MULAI: MOV R0, P1
MOV R6, P0
CJNE R6, #0FEH, TES
ACALL KANAN
TES: CJNE R6, #0FBH, ANGKA0
ACALL KIRI
ANGKA0: CJNE R0, #0FEH, ANGKA1
MOV P0, R0
SJMP MULAI
ANGKA1: CJNE R0, #0FDH, ANGKA2
MOV P0, R0
SJMP MULAI
ANGKA2: CJNE R0, #0FBH, ANGKA3
MOV P0,R0
SJMP MULAI
ANGKA3: CJNE R0, #0F7H, ANGKA4
MOV P0,R0
SJMP MULAI
ANGKA4: CJNE R0, #0EFH, ANGKA5
MOV P0,R0
SJMP MULAI
ANGKA5: CJNE R0, #0DFH, ANGKA6
MOV P0,R0
SJMP MULAI
ANGKA6: CJNE R0, #0BFH, ANGKA7
MOV P0,R0
SJMP MULAI
ANGKA7: CJNE R0, #07FH, MULAI
MOV P0,R0
SJMP MULAI
; SUB RUTIN MUTER KANAN
KANAN : MOV R7, #001H
MOV A, #11111110B
BALI : RR A
MOV P3,A
ACALL TUNDA
DJNZ R7, BALI
RET
; SUB RUTIN MUTER KIWO
KIRI : MOV R7, #001H
MOV A, #11111110B
BALIK :RL A
MOV P3,A
ACALL TUNDA
DJNZ R7, BALIK
RET
; Sub Routine Tunda
TUNDA: MOV R3, #001h
TUNDA1: MOV R1, #0FFH
TUNDA2: MOV R2, #0FFH
TUNDA3: NOP
DJNZ R2, TUNDA3
DJNZ R1, TUNDA2
DJNZ R3, TUNDA1
RET
END
Part 5
ORG 00H
MULAI: MOV A, P1
CJNE A, #0FEh, LONCAT
MOV P0, #00H
SJMP MULAI
LONCAT: CJNE A, #0FDh, MULAI
MOV P0, #0FFh
SJMP MULAI
END
Ref Data Byte Character Font Code for 8051 CPU Assemblers:
http://www.noritake-itron.com/Softview/fonts8051.htm
Assembly Program Turning Off the Stove
Assembly Program Turning Off the Furnace / Stove
;- BAB6_01.ASM -------------------------------------------------------------------
;
; Aplikasi interupsi untuk mematikan dan menghidupkan tungku
; sensor /PANAS dipasang pada /INT0, sensor /DINGIN dipasang pada /INT1
; Relay kompor/oven dipasang pada P1.7
; Sensor /PANAS=0 jika suhu terdeteksi > 21 derajat
; Sensor /DINGIN=0 jika suhu terdeteksi < 19 derajat
;
;---------------------------------------------------------------------------------
ORG 0H
;
LJMP MAIN
;
EX0RLI: CLR P1.5 ; posisi layanan interupsi INT0
RETI ; untuk mematikan kompor
ORG 0013H
EX1RLI: SETB P1.5 ; posisi layanan interupsi INT1
RETI ; untuk menyalakan kompor
;
ORG 30H ; awal dari program utama
MAIN: MOV IE,#85H ; aktifkan interupsi eksternal 0 dan 1
SETB IT0 ; interupsi eksternal sisi negatif untuk INT0
SETB IT1 ; dan INT1
SETB P1.5 ; hidupkan tungku
JB P3.2,SKIP ; jika suhu > 21 derajat
clr P1.5 ; matikan dulu tungkunya
SKIP: SJMP $ ; kalang forever...
END
Hope this is useful & happy learning!
Assembly Programming Assignment Collection
Assembly Program Task Group
Counter
org 0h
Start: Mov TMOD,#00000111b ; mode 3 counter 8 bit counter 1
Setb TR0 ; TR1 = 1, start counting
Get: Mov A, TL0 ; A = TL1
CPL A ; A = NOT A
Mov P0, A ; P0 = A
Sjmp Get ; Looping Forever
End
Experiment Clock Display
second equ 30h
secondTens equ 31h
secondOnes equ 32h
counter20 equ 33h
;
Org 0h
sjmp Start
Org 0bh
Ljmp Interrupt_Timer0
;
Start: mov P3,#11111111b
mov second,#0
call InitTimer
;
Forever:
call ClockDisplay
sjmp Forever ;
;
Interrupt_Timer0:
mov tl0,#0b0h
mov th0,#03ch
djnz Counter20, EndInterrupt
mov Counter20,#20
call DoClock
EndInterrupt:
reti
;
DoClock:
inc second
mov A,second
cjne A,#60,Update
mov second,#0
Update:mov A,second
mov B,#10
DIV AB
mov SecondTens,A
mov SecondOnes,B
ret
;
ClockDisplay:
Setb P2.7
Mov DPTR,#Decoder7Segmen
mov A,secondOnes
Movc A,@A+DPTR
Mov P0,A
Clr P2.7
call delay
;
Setb P2.7
Mov DPTR,#Decoder7Segmen
mov A,secondTens
Movc A,@A+DPTR
Mov P0,A
Clr P2.6
call delay
ret
;
InitTimer:
mov TMOD,#00000001b
mov tl0,#0b0h
mov th0,#03ch
setb ET0 ;Enable Timer 0 Interrupt
setb EA ;Master Interrupt Enable
setb TR0 ;Clock start running
ret
;
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
;========================================
; L O O K U P T A B L E
; Decode to Seven Segmen -> g f e d c b a
;========================================
Decoder7Segmen:
DB 11000000b,11111001b,10100100b,10110000b,10011001b
DB 10010010b,10000010b,11111000b,10000000b,10010000b
;
End
Input Output (I/O)
$mod51
;----------------
; MAIN PROGRAM
;----------------
Main:
MOV A,P2 ; Port 2 sebagai input, dan Accumulator(A) siap menerima ; data dari port 0
MOV P0,A ; Port 0 sebagai output yang menerima data dari accumulator
SJMP Main : kembali ke Main
;---------------
; delay 500 ms
;---------------
DELAY500MS:
PUSH ACC
PUSH 00H
MOV A,#032H ; 500 milli second
X10MS: CALL DELAY10MS
DJNZ ACC,X10MS
POP 00H
POP ACC
RET
;-------------
; DELAY 10 ms
;-------------
DELAY10MS:
PUSH ACC
PUSH 00H
MOV 00H,#050H
D10MS1: MOV A,#0C8H
DJNZ ACC,$
DJNZ R0,D10MS1
POP 00H
POP ACC
RET
END
Experiment Seven Segment
ORG 00H
MULAI : MOV DPTR,#TULISAN
MOV R6,#05H
ULANG : CLR A
MOVC A,@A+DPTR
INC DPTR
MOV P0,A
MOV P2,A
;MOV P1,#011H
;MOV P2,#001H
;RR A
ACALL TUNDA
DJNZ R6,ULANG
SJMP MULAI
TUNDA: MOV R0, #05H
TUNDA1: MOV R1, #0EFH
TUNDA2: MOV R2, #0FFH
TUNDA3: NOP
DJNZ R2,TUNDA3
DJNZ R1,TUNDA2
DJNZ R0,TUNDA1
RET
TULISAN:DB 00111111B, 006H, 01011011B,01001111B ,01100110B
ANGKA: DB 11111110B,11111101B,11111011B,11110111B,11101111B,1101111B,10111111B,01111111B,10111111B,11011111B,11101111B,11110111B,11111011B,11111101B,11111110B
END
Turning on the Light on Port 0
Part 1
; Program menghidupkan lampu pada Port 0 dengan cara
; menekan tombol 1 pada Port 1 dan mematikan dengan cara
; menekan tombol 2 pada port 1
ORG 00H
MULAI: MOV A, P1
CJNE A, #0FEh, LONCAT
MOV P0, #00H
SJMP MULAI
LONCAT: CJNE A, #0FDh, MULAI
MOV P0, #0FFh
SJMP MULAI
END
Part 2
; Program menghidupkan lampu pada Port 0 dengan
; menekan tombol 1 untuk menghidupkan lampu 1, tombol 2
; untuk menghidupkan lampu 2 dan seterusnya.
ORG 00H
MULAI: MOV A, P1
CJNE A, #0FEH,LONCAT01
MOV P0, #0FEH
SJMP MULAI
LONCAT01: CJNE A, #0FDH, LONCAT02
MOV P0, #0FDH
SJMP MULAI
LONCAT02: CJNE A, #0FBH, LONCAT03
MOV P0, #0FBH
SJMP MULAI
LONCAT03: CJNE A, #0F7H, LONCAT04
MOV P0, #0F7H
SJMP MULAI
LONCAT04: CJNE A, #0EFh, LONCAT05
MOV P0, #0EFh
SJMP MULAI
LONCAT05: CJNE A, #0DFH, LONCAT06
MOV P0, #0DFH
SJMP MULAI
LONCAT06: CJNE A, #0BFH, LONCAT07
MOV P0, #0BFH
SJMP MULAI
LONCAT07:
CJNE A, #07FH, MULAI
MOV P0, #07FH
SJMP MULAI
END
Part 3
; Program menghidupkan lampu pada Port 1 dengan cara
; menekan tombol 1 untuk menghidupkan lampu 1, tombol 2
; untuk menghidupkan lampu 2 dan seterusnya dengan waktu
; nyala yang berbeda sesuai dengan pengaturan lamanya
; delay.
;======================================================================
ORG 00H
MULAI: MOV A, P1
CJNE A, #0FEH, LONCAT01
MOV P0, #0FEH
ACALL DELAY1
MOV P0, #0FFH
SJMP MULAI
LONCAT01: CJNE A, #0FDH, LONCAT02
MOV P0, #0FDH
ACALL DELAY2
MOV P0, #0FFH
SJMP MULAI
LONCAT02: CJNE A, #0FBH, LONCAT03
MOV P0, #0FBH
ACALL DELAY3
MOV P0, #0FFH
SJMP MULAI
LONCAT03: CJNE A, #0F7H, LONCAT04
MOV P0, #0F7H
ACALL DELAY4
MOV P0, #0FFH
SJMP MULAI
LONCAT04: CJNE A, #0EFH, LONCAT05
MOV P0, #0EFH
ACALL DELAY5
MOV P0, #0FFH
SJMP MULAI
LONCAT05: CJNE A, #0DFH, LONCAT06
MOV P0, #0DFH
ACALL DELAY6
MOV P0, #0FFH
SJMP MULAI
LONCAT06: CJNE A, #0BFh, LONCAT07
MOV P0, #0BFH
ACALL DELAY7
MOV P0, #0FFH
SJMP MULAI
LONCAT07: CJNE A, #07FH, MULAI
MOV P0, #07FH
ACALL DELAY8
MOV P0, #0FFH
SJMP MULAI
; Sub Routin Delay
DELAY1: MOV R0, #01H
ACALL TUNDA1
RET
DELAY2: MOV R0, #04H
ACALL TUNDA1
RET
DELAY3: MOV R0, #08H
ACALL TUNDA1
RET
DELAY4: MOV R0, #0BH
ACALL TUNDA1
RET
DELAY5: MOV R0, #0FH
ACALL TUNDA1
RET
DELAY6: MOV R0, #014H
ACALL TUNDA1
RET
DELAY7: MOV R0, #018H
ACALL TUNDA1
RET
DELAY8: MOV R0, #01BH
ACALL TUNDA1
RET
; Sub Routin Tunda
TUNDA1: MOV R1, #0FFH
TUNDA2: MOV R2, #0FFH
TUNDA3: NOP
DJNZ R2, TUNDA3
DJNZ R1, TUNDA2
DJNZ R0, TUNDA1
RET
END
Experiment Register
Part 1
$mod51
;----------------
; MAIN PROGRAM
;----------------
Main:
setb rs1
setb rs0
mov r0,#88H
mov r1,#88H
mov r2,#88H
mov r3,#88H
mov r4,#88H
mov r5,#88H
mov r6,#88H
mov r7,#88H
END
Part 2
$mod51
;----------------
; MAIN PROGRAM
;----------------
Main: mov r0,#09H
mov r1,#70H
mov r2,#02H
mov r3,#72H
mov r4,#64H
mov r5,#03H
mov r6,#40H
mov r7,#55H
END
Part 3
ORG 00H
MULAI: MOV P0, #0f0h
ACALL TUNDA
MOV P0, #00fh
ACALL TUNDA
SJMP MULAI
TUNDA: MOV R0, #01H
TUNDA1: MOV R1, #0EFH
TUNDA2: MOV R2, #0FFH
TUNDA3: NOP
DJNZ R2,TUNDA3
DJNZ R1,TUNDA2
DJNZ R0,TUNDA1
RET
END
Activating Relay
$mod51
;----------------
; MAIN PROGRAM
;----------------
Main:
CLR P3.0 ; Mengaktifkan Relay 1
CLR P3.1 ; Mengaktifkan Relay 2
SJMP Main ; Kembali ke Main
;---------------
; delay 500 ms
;---------------
DELAY500MS:
PUSH ACC
PUSH 00H
MOV A,#032H ; 500 milli second
X10MS: CALL DELAY10MS
DJNZ ACC,X10MS
POP 00H
POP ACC
RET
;-------------
; DELAY 10 ms
;-------------
DELAY10MS:
PUSH ACC
PUSH 00H
MOV 00H,#050H
D10MS1: MOV A,#0C8H
DJNZ ACC,$
DJNZ R0,D10MS1
POP 00H
POP ACC
RET
END
Beginner Class Assignment
ORG 00H
MOV A, #0C3H
MOV B, #022H
DIV AB
MOV 20H, B
MOV 21H, A
END
ORG 00H
MOV A, #06H
INC A
MOV R0, #09H
INC R0
MOV 15H, #04H
INC 15H
MOV R1, #20H
MOV 20H, #00H
MOV 21H, #50H
INC @R1
INC R1
INC @R1
END
ORG 00H
MOV DPH, #012H
MOV DPL, #0FEH
INC DPTR
INC DPTR
INC DPTR
INC DPTR
END
ORG 00H
MOV A, #78H
MOV R2, #55H
SETB C
ADDC A, R2
MOV 20H, A
DA A
MOV 21H, A
END
ORG 00H
MOV A, #001101010B
JBC ACC.1, LONCAT
MOV R1, #77H
LONCAT: MOV R2, #66H
END
ORG 00H
MOV P1, #0000101B
MOV A, #10010010B
JB P1.3, LOMP1
JB ACC.3, LOMP2
NOP
LOMP1: MOV R1, #88H
LOMP2: MOV R2, #66H
END
Hope this is useful & happy learning!
Program Assembly Traffic Light Sederhana
Program Assembly Traffic Light Sederhana
; Program penyalaan lampu jalan dengan nyala tiap dua
; lampu secara berurutan.
ORG 00H
MULAI: MOV P0, #0FCH
ACALL TUNDA
MOV P0, #0F3H
ACALL TUNDA
MOV P0, #0CFH
ACALL TUNDA
MOV P0, #03FH
ACALL TUNDA
SJMP MULAI
; Sub Routine Tunda
TUNDA: MOV R0, #003H
TUNDA1: MOV R1, #0FFH
TUNDA2: MOV R2, #0FFH
TUNDA3: NOP
DJNZ R2, TUNDA3
DJNZ R1, TUNDA2
DJNZ R0, TUNDA1
RET
END
Hope this is useful & happy learning!
Flashing Light Animation Assembly Program
Flashing Light Animation Assembly Program
Part 1
;==========================
; PROGAM UTAMA =
;==========================
ORG 0H
MULAI:
LCALL MODE1
LCALL MODE1
LCALL MODE1
LCALL MODE1
LCALL MODE1
LCALL MODE1
LCALL MODE2
LCALL MODE2
LCALL MODE2
LCALL MODE2
LCALL MODE2
LCALL MODE3
LCALL MODE3
LCALL MODE3
LCALL MODE3
LCALL MODE4
LCALL MODE4
LCALL MODE4
LCALL MODE4
LCALL MODE5
LCALL MODE5
LCALL MODE5
LCALL MODE6
LCALL MODE6
LCALL MODE6
LCALL MODE6
LJMP MULAI
;
;==========================
; MODE1 = GESER KIRI =
;==========================
MODE1:
ORG 0H
MOV R4,#08H
MOV A,#0FEH
MULAI1:
MOV P1,A
LCALL DELAY
RL A
DJNZ R4,MULAI1
RET
;
;===========================
; MODE2 = GESER KANAN =
;===========================
MODE2:
ORG 0H
MOV R4,#08H
MOV A,#0EFH
MULAI2:
MOV P1,A
LCALL DELAY
RR A
DJNZ R4,MULAI2
RET
;
;=================================
; MODE3 = BELAH DARI TENGAH =
;=================================
MODE3:
ORG 0H
MOV R4,#08H
MOV DPTR,#DATA1
LOOP1: CLR A
MOVC A,@A+DPTR
MOV P1,A
LCALL DELAY
INC DPTR
DJNZ R4,LOOP2
DATA1: DB 0E7H,0DBH,0BDH,07EH
RET
;
;==============================
; MODE4 = TUTUP KETENGAH =
;==============================
MODE4:
ORG 0H
MOV R4,#08H
MOV DPTR,#DATA2
LOOP2: CLR A
MOVC A,@A+DPTR
MOV P1,A
LCALL DELAY
INC DPTR
DJNZ R4,LOOP2
DATA2: DB 07EH,0BDH,0DBH,0E7H
RET
;
;==============================
; MODE5 = KEDIP 8 BIT =
;==============================
MODE5:
ORG 0H
MOV A,00H
MOV P1,A
LCALL DELAY
MOV A,0FFH
MOV P1,A
LCALL DELAY
RET
;
;==============================
; MODE6 = KEDIP 4 BIT =
;==============================
MODE6:
ORG 0H
MOV A,00FH
MOV P1,A
LCALL DELAY
MOV A,0F0H
MOV P1,A
LCALL DELAY
RET
;
DELAY: MOV R0,#0FFH
DELAY1: MOV R1,#0FFH
DELAY2: DJNZ R1,DELAY2
DJNZ R0,DELAY1
RET;
END
Part 2
ORG 00H
MULAI: MOV A, P1
CJNE A, #0FEh, LONCAT
ACALL MAJU
SJMP MULAI
LONCAT: CJNE A, #0FDh, MULAI
ACALL MUNDUR
SJMP MULAI
MAJU: MOV P0, #00000011b
ACALL TUNDA
MOV P0, #00000110b
ACALL TUNDA
MOV P0, #00001100b
ACALL TUNDA
MOV P0, #00001001b
ACALL TUNDA
SJMP MAJU
MUNDUR: MOV P0, #00001100b
ACALL TUNDA
MOV P0, #00000110b
ACALL TUNDA
MOV P0, #00000011b
ACALL TUNDA
MOV P0, #00001001b
ACALL TUNDA
SJMP MUNDUR
; Sub Routine Tunda
TUNDA: MOV R0, #001h
TUNDA1: MOV R1, #0FFH
TUNDA2: MOV R2, #0FFH
TUNDA3: NOP
DJNZ R2, TUNDA3
DJNZ R1, TUNDA2
DJNZ R0, TUNDA1
RET
END
Part 3
ORG 00H
MULAI: MOV A, P1
CJNE A, #0FEh, LONCAT
ACALL MAJU
SJMP MULAI
LONCAT: CJNE A, #0FDh, MULAI
ACALL MUNDUR
SJMP MULAI
MAJU: MOV R7,#01
BALEK: MOV P0, #00000011b
ACALL TUNDA
MOV P0, #00000110b
ACALL TUNDA
MOV P0, #00001100b
ACALL TUNDA
MOV P0, #00001001b
ACALL TUNDA
DJNZ R1,BALEK
SJMP MULAI
MUNDUR: MOV R6,#01
BALI: MOV P0, #00001100b
ACALL TUNDA
MOV P0, #00000110b
ACALL TUNDA
MOV P0, #00000011b
ACALL TUNDA
MOV P0, #00001001b
ACALL TUNDA
DJNZ R1,BALI
SJMP MULAI
; Sub Routine Tunda
TUNDA: MOV R0, #001h
TUNDA1: MOV R1, #0FFH
TUNDA2: MOV R2, #0FFH
TUNDA3: NOP
DJNZ R2, TUNDA3
DJNZ R1, TUNDA2
DJNZ R0, TUNDA1
RET
END
Hope this is useful & happy learning!
Demo Assembly Program Running a 16x2 LCD
Demo Assembly Program Running a 16x2 LCD
;-----------------------------------------
;Program Demo untuk menjalankan LCD 16 x 2
;Character FN : HL18.H51
;-----------------------------------------
;
org 0h
nop
ljmp mulai
;
write_inst:
mov P2,#0h ;untuk memuliskan
mov P0,R1 ;intruksi ke LCD
setb P2.6 ;module
clr P2.6
acall delay
ret
;
write_data:
mov P2,#80h ;untuk menuliskan
mov P0,R1 ;data ke LCD
setb P2.6 ;module
clr P2.6
acall delay
ret
;
delay: mov R0,#0
delay1: mov R5,#50h
djnz R5,$
djnz R0,delay1
ret
;
Ldelay: mov R2,#030h
Ld1: acall delay
djnz R2,Ld1
ret
;
tulis: mov R4,#3
mov DPTR,#Haline
barisa: mov R3,#16
mov R1,#80h
acall write_inst
tulis1: clr A
movc A,@A+DPTR
mov R1,A
Inc DPTR
acall write_data
djnz R3,Tulis1
;
barisb: mov R3,#16
mov R1,#0C0h
acall write_inst
tulis2: clr A
movc A,@A+DPTR
mov R1,A
Inc DPTR
acall write_data
djnz R3,Tulis2
acall Ldelay
djnz R4,barisa
ret
;
mulai:
mov R1,#03Fh
acall write_inst
acall write_inst
mov R1,#0Dh
acall write_inst
mov R1,#06h
acall write_inst
mov R1,#01h
acall write_inst
mov R1,#0Ch
acall write_inst
acall tulis
sjmp mulai
;
Haline: DB 'SELAMAT DATANNG '
DB 'Sdr. Teguh dkk. '
DB 'di. D . Maninjau'
DB 'No. 58 Sawojajar'
DB 'MALANG INDONESIA'
DB 'Phone/Fax 719418'
;
end
Hope this is useful & happy learning!