Instruction Set and Assembly Language Programming 179
Every processor offers some scope to implement these types of procedures. It may or may not be
implemented by a single instruction. For example, 8051 offers DJNZ instruction, which may be directly
used to implement the for–next loop. However, no such single instruction is available in 8085. Therefore,
in the case of 8085 processor, it has to be implemented by ‘DCR reg’ followed by ‘JNZ’ instruction.
6.9.6 Program Branching
Both conditional as well as unconditional program branching instructions are offered by all processors.
However, their number varies with the processor. Conditional program branching instructions are essen-
tial for all programs. The type of conditions used for branching depends upon speci c programming
domain. However, carry and zero are most widely used conditions for program branching.
Intel 8085 microprocessor provided conditional branching instructions for all of its ags of its ag
register. The same is valid for 8086 processor, which offers more number of ags. In 8051, conditional
branching instructions are offered at optimum level, because its bit-condition oriented jump instruction
(e.g., JB bit addr., rel. addr. ) may check its ag-register (PSW) bit-wise and then take the decision.
Both conditional as well as unconditional program branching are generally implemented by reload-
ing the program counter (PC) with the branching address. In normal conditions, PC is incremented by
one to fetch the next instruction’s code. This reloading forces the processor to fetch the next instruction
from the target address according to the reloaded information.
6.9.7 Subroutine Calls
No software instruction set can be complete without instructions for subroutine call and return instruc-
tions. However, whether conditioned call and conditioned return instructions are genuinely required or
not (as in case of 8085 instruction set) is a matter of debate.
Subroutine calls may be visualized as a special type of jump instruction. Just like the normal jump
instruction, the PC, in this case, is loaded with the address of the subroutine being called and the con-
trol branches to that location and starts executing from there. However, the basic difference may be
observed in subroutine calls is that the return address (the address of the next executable instruction
just after the call instruction) is stored on the stack top by the processor before branching. As every
subroutine has to execute a return instruction at its end, this return address, saved on the stack top, is
reloaded in the PC and the processor starts executing from the very location that it had left at the time
of branching for the call instruction.
6.10 ASSEMBLER
We have already indicated that programs, developed in assembly language using the instruction set of
any processor, to be converted to its machine language format before its execution by that processor.
This translation may be carried out in two ways, either by hand assembly or through an assembler .
In the case of hand assembly, a conversion table is used to translate each instruction to its corre-
sponding binary form, which is also known as machine code. Moreover, the branching addresses and
relative addresses are also calculated by long hand. Essentially, this is a tedious process and suitable
only for those programs that are very small, say within 10 to 15 instructions. For longer programs, it is
preferable to use an assembler to get the job done, unless the assembly language software developer is
an adventurous one.
M06_GHOS1557_01_SE_C06.indd 179M06_GHOS1557_01_SE_C06.indd 179 4/29/11 5:09 PM4/29/11 5:09 PM
180 Computer Architecture and Organization
6.10.1 Two-pass Assembler
The input for any assembler is the source code , i.e., the assembly language program. Generally,
an editor is offered by most assemblers to write the assembly language program and save it. In the
absence of it, any word processor may also be used to write the assembly language program. The
output of the assembler is the object code , which contains the executable version of the source code
in machine language.
This source code is scanned by the assembler, one line at a time, and all labels, variables and con-
stants are earmarked and assigned suitable addresses to hold their values. The table generated for this
purpose is generally known as symbol table or SymTab. Considering the small program segment shown
in Figure 6.18, the SymTab would generate only one entry, START, and as there is no ORG directive,
the assembler would be assigning address 0000H for it.
The source code is then scanned again, from its start, and this time all the instructions are translated
to their respective machine codes, and all variables are replaced by their respective values utilizing the
SymTab entries. To clarify, for the same example program segment of Figure 6.18, the assembler would
replace the label START of the second instruction ( JZ START ) by 0000H, the value obtained from its
now-complete SymTab. It is needless to indicate that the mnemonic JZ also would be translated to its
machine code at the same time. After completion of this scanning (or second pass), the code generated
by the assembler would be the object code in binary form and may be directly executed. This may now
be saved and/or executed. As it takes two cycles of scanning of the entire source code, assemblers using
this method are known as two-pass assemblers.
6.10.2 One-pass Assembler
Instead of using two separate passes to generate the object from source code, some assemblers use
only one pass. In this case, machine codes of all instructions are generated in pass-one itself, instead
of pass-two, as in the two-pass assemblers. All backward references are also lled up, as their values
are already known. In our example case, shown in Figure 6.9, the label START in the second line of
the program is a backward reference as its value is already implied in the rst line of the program
(at the back-side of the second instruction). However, in some cases it might be a forward reference
and those portions of the so-far generated object code are left vacant. At the end of the rst pass, all
these vacant places are lled up by the one-pass assembler and a complete object code is available
for the user.
At the development stage of the chess playing program by the present author, the 2.5 K
(approximately) size assembly language program on Zilog Z80 processor had to be modified at
least 25 times to make it error-free and fully functional. This had been done by hand coding by
the present author, without the help of any assembler, because Z80 assembler was not readily
available. This was during 1986–1988, before the era of internet. However, this may be taken
as an example of exception.
F
O
O
D
F
O
R
T
H
O
U
G
H
T
M06_GHOS1557_01_SE_C06.indd 180M06_GHOS1557_01_SE_C06.indd 180 4/29/11 5:09 PM4/29/11 5:09 PM
Instruction Set and Assembly Language Programming 181
6.10.3 Editor, Loader, Linker and Debugger
It is already indicated that the editor is the software, which is used for assembly language program
development. However, apart from editor, there are other supporters of assembler. They are loader,
linker and debugger.
Loader is the software responsible for loading the object code within an assigned area of primary
memory of the system, so that the code may be executed directly. In this case, it might be noted that the
absolute addresses within the object code might have to be changed to their physical addresses according
to the address-space available in the assigned memory portion. This change is carried out by the loader.
In many cases, several subroutines are developed and saved under separate le names. For some
other cases, a few library routines might have to be attached with the object code. It is the duty of the
linker to perform these assignments.
Debugger is responsible for executing the object code, available within primary memory. For the
purpose of debugging, break pointing and single stepping facilities are offered by the debugger. Break-
point is used to stop the object code execution at a pre-assigned location, indicated by the user before the
start of object code execution. If there is a breakpoint after every instruction, it is designated as single
stepping. In both cases, all register contents and memory locations are saved for the purpose of inspec-
tion by the user. If necessary, they may be veri ed and changed before resuming the execution from the
same point at which it was interrupted. Essentially, these are used at the initial stages of the software
development for the purpose of error-debugging.
6.10.4 Macro
In assembly language programming, sometimes it might be necessary to repeat a few steps of a program
segment at some other place of the program. Although, this may be achieved by rewriting those instruc-
tions again, provision of macro helps the program developer to avoid this additional work load. If any
program segment is de ned as a macro, with a speci c name, the same name may be used instead of
rewriting those steps, so that at the time of assembly, the assembler replaces those desired instructions
and thus expands the macro . It is a common practice to indicate the end of any macro by the assembler
directive, e.g., macroend .
Macros are different from subroutines by the characteristics, that there is no need to place any return
instruction in macro, like a subroutine. Secondly, unlike subroutines, macros are expanded to concerned
instructions before the program execution starts. As we know, in case of subroutines, no such instruction
replacement is necessary. Therefore, usage of macros does not shorten the object code of any assembly
language program but only its source code might be more compact.
The reader is reminded that no such address change by loader is required in the case of rela-
tive addressing, used in instructions.
F
O
O
D
F
O
R
T
H
O
U
G
H
T
M06_GHOS1557_01_SE_C06.indd 181M06_GHOS1557_01_SE_C06.indd 181 4/29/11 5:09 PM4/29/11 5:09 PM
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.26.108