Saturday, 29 September 2018

Microprocessor Lab 80386 Experiment no 03


Experiment No 03

Title: 
            Write X86/64 ALP to convert 4-digit Hex number into its equivalent BCD number and 5-digit BCD number into its equivalent HEX number. Make your program user friendly to accept the choice from user for:
(a) HEX to BCD b) BCD to HEX (c) EXIT.
Display proper strings to prompt the user while accepting the input and displaying the result. (Wherever necessary, use 64-bit registers)

Objectives:
            Basics of the Assembly language programming
Knowledge of the instruction set.
            Knowledge of nasm
Environment:
1.      OS: ubuntu 12.10
2.      Assembler: NASM
3.      Linker: ld
Theory:
 Segment directives
These directives indicate to assembler the order in which to load segment. When it encounter one of these directives, it interprets all subsequent instructor as belonging to the indicated segment (until the ne xt directives is encounter).
.stack <size>; specified .code .data

Data type declaration
As has been previously discu ssed, data can be of several diff erent lengths and assembler
must be able to decide what length a specific constant (or variable) is. This can be down using data type declaration in conjunction with a constant declaration or variable assignment .this is akin to strong typing of variable in high level language .the data types are:
Byte (8 bit quantity)—synonyms are byte and db
Word (16) -- synonyms are word dw
Dword (32bit) -- synonyms are dword and dd
Qword (64bit) -- synonyms with dq
Tword (128bit) -- synonyms with dt

An example of their use is:
MOV AX, word VAR         ; moves a 16-bit Variable VAR into AX

Instruction Used:
1. PUSH:-Push word onto stack.
2. POP:-Pop word off stack.
3. DIV:-Divide byte/word
4. XOR: - Exclusive or byte/word
5. JA/JNBE:-Jump if above/not below or equal
6. JB/JNAE:-Jump if below /not above or equal
7. JG/JNLE:-Jump if /not less nor equal
8. JL/JNGE:-Jump if less /not greater nor equal
9. INT:-It allows ISR to be activated by programmer & external H\W device

Algorithm:
 HEX to BCD
1. Define variable on data segment.
2. Display message on screen ENTER 4-DIGIT HEX NO.
3. Accept BCD NO from user.
4. Transfer 0AH as a divisor in one of the register.
5. Divide the no by 0AH
6. PUSH reminder in one of the register
7. Increment Count _1.
8. Repeat Till BCD NO is not zero go to step 5.
9. Pop the content of Reminder.
10. Display result by calling display procedure.
11. Decrement Count _1, till Count is not zero repeat step 9 else go to step 12.
12. Stop

BCD to HEX
1. Define variables in data segment
2. Display message on screen ENTER 5-DIGIT BCD NO.
3. Accept single digit from user
4. Transfer 10000 to multiplier
5. Multiply accepted BCD digit by multiplier & add it to RESULT variable.
6. Accept single digit from user
7. Transfer 1000 to multiplier
8. Multiply accepted BCD di git by multiplier & add it to RES ULT variable.
9. Accept single digit from u ser
10. Transfer 100 to multiplier
11. Multiply accepted BCD di git by multiplier & add it to RES ULT variable.
12. Accept single digit from u ser
13. Transfer 10 to multiplier
14. Multiply accepted BCD digit by multiplier & add it to RESULT variable.
15. Accept single digit from user
16. Transfer 1 to multiplier
17. Multiply accepted BCD digit by multiplier & add it to RESULT variable.
18. Display result by calling display procedure
19. Stop.

 Procedure for accept numbers: (ASCII to HEX)
1. Read a single character/digit from keyboard using function 0AH of INT 21H
2. Convert ASCII to HEX as per following:
            a. Compare its ASCII with 30H if No is less than 0 (i.e case of -ve no given) then go to
step f else go to step c.
b. Compare its ASCII with 39H if No is greater than 9 (i.e case of character A – F given)
then go to step f else go to step c .
c. Store the resultant bit in NUM Variable.
d. Check whether four digits (16-bit number) or two digits (8-bit number) are read; if yes
then go to display procedure else go to step 1 for next bit
e. Till counter is zero go to accept procedure.
f. Display massage “I/P is invalid BCD number” & go to step 17.
3. End of accept procedure.

Procedure for display Result: (HEX to ASCII)
1. Compare 4 bits (one digit) of number with 9
2. If it is <= 9 then go to step 4 else go to step 3
3. Add 07 to that number
4. Add 30 to it
5. Display character on screen using function 02 of INT 21H
6. Return to main routine
7. End of display procedure.

  
  

Microprocessor 80386 lab Experiment no 02


Experiment No: 02
Title: 
            Write X86/64 ALP to perform non-overlapped and overlapped block transfer (with and without string specific instructions). Block containing data can be defined in the data segment.

Objective:-
1)      To study the basic concepts of assembly language.
2)      To practically implement instruction set of 80386 microprocessor.
3)      To study How to accept and display the numbers by using assembly programming theory.
Environment:
1.      OS: ubuntu 12.10
2.      Assembler: NASM
3.      Linker: ld
Theory:
                        Program for non-overlapped and overlapped block transfer of array elements. Takes the array elements from the user and also the number of elements to be overlapped in overlapped transfer. Block transfer here, refers to moving of block of data within the memory to a different location. In non-overlapped transfer we move the data to a completely new location. It is easily accomplished by copying the data using two pointers, one data byte at a time. In overlapped transfer the data block is shifted slightly from the present position, thus some of the starting elements may overlap with the old position of the last elements in the array. They are therefore copied in reverse order.
Registers:
            Registers are places in the CPU where a number can be stored and manipulated. There are three sizes of registers: 8-bit, 16-bit and on 386 and above 32-bit. There are four different
Types of registers:
1. General Purpose Registers,
2. Segment Registers,
3. Index Registers,
4. Stack Registers.

General Registers – Following are the registers that are used for general purposes in 80386
EAX accumulator (32 bit)
 AX accumulator (16 bit)
AH accumulator high-order byte (8 bit)
AL accumulator low-order byte (8 bit)

EBX   (32 bit)
BX  (16 bit)
BH  (8 bit)
BL (8 bit)

ECX count and accumulator (32 bit)
CX count and accumulator (16 bit)
CH count high order byte (8 bit)
CL count low order byte (8 bit)

EDX data and I/O address (32 bit)
DX data and I/O address (16 bit)
DH data high order byte (8 bit)
DL data low order byte (8 bit)

Segment Registers - These registers are used to calculate 20 bit address from 16 bit registers.
CS code segment (16 bit)
DS data segment (16 bit)
SS stack segment (16 bit)
ES extra segment (16 bit)

Index Registers - These registers are used with the string instructions.
EDI destination index (32 bit)
ESI source index (32 bit)

Pointers - These registers are used with the segment register to obtain 20 bit
addresses
ESP stack pointer (32 bit)
EBP base pointer (32 bit)

CS, Code Segment (16 bit)
Used to “point” to Instructions, Determines a Memory Address (along with IP)
Segmented Address written as CS:IP

DS, Data Segment (16 bit)
Used to “point” to Data. Determines Memory Address (along with other registers)

ES, Extra Segment (16 bit) allows 2 Data Address Registers
SS, Stack Segment (16 bit) Used to “point” to Data in Stack Structure (LIFO)
Used with SP or BP
SS:SP or SS:BP are valid Segmented Addresses

EIP instruction pointer (32 bit)
IP, Instruction Pointer
Used to “point” to Instructions Determines a Memory Address (along with CS)
Segmented Address written as CS:IP
SI, Source Index;
DI, Destination Index
Used to “point” to Data Determines Memory Address (along with other registers)
DS, ES commonly used
ESP, Stack Pointer;
EBP, Base Pointer
Used to “point” to Data in Stack Structure (LIFO) Used with SS SS:SP or SS:BP are valid Segmented Addresses

Memory address calculations
The 80386 uses a 32 bit address bus but the registers are sixteen bit as well as 32 bit. To derive 32 bit addresses from the register s two registers are combined. Every memory reference uses one of the four segment registers plus an offset and/or a base pointer and/or a index register. The segment register is multiplied by sixteen (shifted to the left four bits) and added to the sixteen bit result of the offset calculation.

The 8086 provides four segment registers for address calculations. Each segment register is assigned a different task. The code segment register is always used with the instruction pointer (also called the program counter) to point to the instruction that is to be executed next. The stack segment register is always used with the stack pointer to point to the last value pushed onto the stack. The extra segment is general purpose segment register. The data segment register is the default register to calculate data operations, this can be overridden by specifying the segment register. For example mov ax,var1 would use the offset var1 and the data segment to calculate the memory reference but mov ax,ss:var1 would use the offset var1 and the stack segment register to calculate the memory reference. The offset can be calculated in a number of ways. Their are three elements that can make up an offset. The first element is a base register, this can be one of the BX of BP registers (the BP register defaults to the stack segment). The second element is one of the index register, SI or DI. The third element is a displacement. A displacement can be a numerical value or an offset to a label. An offset can contain one to three of these elements, making a total of sixteen possibilities.

BX SI
or + or + Displacement
BP DI
(base) (index)
The offset to a label in calculated using the assembler directive OFFSET. This directive makes the assembler calculate the distant from the start of the segment that the label resides in to the label.

Memory Segmentation
x86 Memory Partitioned into Segments
– 8086: maximum size is 64K (16-bit index reg.)
– 8086: can have 4 active segments (CS, SS, DS, ES)
– 8086: 2-data; 1-code; 1-stack
– x386: maximum size is 4GB (32-bit index reg.)
– x386: can have 6 active segments (4-data; FS, GS)

Why have segmented memory?
Other microprocessors could only address 64K since they only had a single 16-bit MAR (or smaller). Segments allowed computers to be built that could use more than 64K memory (but not all at the same time).


Note that segments can overlap. This means that two different logical addresses can refer
to the same physical address (aliasing).In non-overlapping method, address of source is totally different from address of destination. Therefore, we can directly transfer the data using MOVSB/MOVSW    instruction for transferring the data. The blocks are said to be overlapped if some of the memory locations are common for both the blocks.

Case I: If address in SI is greater than address in DI then start the data transfer from last
memory location keeping DF=1.

Case II: If address in SI is less than address in DI, then start the data transfer from first
memory location by keeping DF=0.

Algorithm:-
1. Start
2. Initialize data section
3. Load counter with number element for Addition
4. Locate first location of array of Number in Pointer Register
5. Initialize result-low and result high to 00
6. Scan the number from user and convert it into Hex
7. Increment Location Pointer Register.
8. Decrement counter
9. Jump tostep 6 if counteris not zero
10. Locate first location of arrayofnumbers inapointer register
 11. Initialize counterwith numberof elements for addition
 12. Add the element ofarraypointed bypointerregister
 13. Check the carryofaddition.If carryisgenerated then go to step 14elsegoto step15
 14. Increment result-high register
 15. Increment pointer registerto array
 16. Decrement counter
 17. Jump tostep 12 if counteris not equal to zero
 18. Displaythecontent ofResult-High ascarryof addition byconvertinghextoASCII
 19. Displaythecontent ofResult-Lowas result of addition byconvertinghextoASCII
 20. Stop


  



  

Microprocessor 80386 Lab Experiment no 1



Experiment  No:01
Title: 
Write X86/64 ALP to count number of positive and negative numbers from the array.

Objectives:
1)      To study  the basic concepts of assembly language .
2)       To  Practically implement instruction set of 80386 microprocessor .
3)      To study How to accept and display the numbers by using assembly programming  theory.
Environment:
1.      OS: ubuntu 12.10
2.      Assembler: NASM
3.      Linker: ld

Theory:
          To count the number of positive number, negative number, and zero from the given set of numbers entered by the user in C++ programming, you have to ask to the user to enter some set of numbers (10 numbers here). Now to find occurrence of positive, negative and zero from the given set of numbers, just check all the numbers using for loop whether the number is 0, less than zero or greater than 0 to count the occurrence of positive, negative and zero as shown here in the following program.

What is ALP?
Assembly language Program is mnemonic representation of machine code.

Which assembler used in execution of ALP?

            Three assemblers available for assembling the programs for IBM-PC are:
1. Microsoft Micro Assembler(MASM)
2. Borland Turbo Assembler (TASM)
3. Net wide Assembler (NASM)

Assembly Basic Syntax
            An assembly program can be divided into three sections:
1. The data section
2. The bss section
3. The text section

The data Section: 
            The data section is used for declaring initialized data or constants. This data does not change at runtime. Youcan declare various constant values, file names or buffer size etc. in this section.The syntax for declaring data section is:
section .data

The bss Section :
            The bss section is used for declaring variables. The syntax for declaring bss section is:
section .bss

The text section:
            The text section is used for keeping the actual code. This section must begin with the Declaration global main,  which tells the kernel where the program execution begins.  The syntax for declaring text section is:
section .text

global main
main:
Assembly Language Statements

Assembly language programs consist of three types of statements:

1. Executable instructions or instructions

2. Assembler directives or pseudo-ops

3. Macros

            The executable instructions or simply instructions tell the processor what to do. Each instruction consists of an operation code (opcode). Each executable instruction generates one  machine language instruction.  The assembler directives or pseudo-ops tell the assembler about the various aspects of the assembly process.
These are non-executable and do not generate machine language instructions.
 Macros are basically a text substitution mechanism.
 Assembly System Calls
 System calls are APIs for the interface between user space and kernel space. We are using the
 system calls sys_write and sys_exit for writing into the screen and exiting from the program
 respectively.

Linux System Calls
 You can make use of Linux system calls in your assembly programs. You need to take the
 following steps for using Linux system calls in your program:

·         Put the system call number in the EAX register.
·         Store the arguments to the system call in the registers EBX, ECX, etc.
·         Call the relevant interrupt (80h)
·         The result is usually returned in the EAX register

            There are six registers that stores the arguments of the system call used. These are the EBX, ECX, EDX, ESI, EDI, and EBP. These registers take the consecutive arguments, starting with the EBX  register. If there are more than six arguments then the memory location of the first argument is stored in the EBX register.

The following code snippet shows the use of the system call sys_exit:
MOV EAX, 1       ; system call number (sys_exit)
INT 0x80              ; call kernel

The following code snippet shows the use of the system call sys_write:
MOV EDX, 4            ; message length
MOV EBX,1             ; file descriptor (stdout)
MOV ECX, MSG      ; message to write
MOV EAX,4             ; system call number (sys_write)
INT 0x80                    ; call kernel

       OPEN File
mov rax, 2            ; 'open' syscall
mov rdi, fname1   ; file name
mov rsi, 0             ;
mov rdx, 0777       ; permissions set
Syscall
mov [fd_in], rax

      OPEN File/Create file
mov rax, 2            ; 'open' syscall
mov rdi, fname1   ; file name
mov rsi, 0102o      ; read and write mode,                                          create if not
mov rdx, 0666o       ; permissions set
Syscall
mov [fd_in], rax

      READ File
mov rax, 0            ; ‘Read' syscall
mov rdi, [fd_in]     ; file Pointer
mov rsi, Buffer      ; Buffer for read
mov rdx, length     ; len of data want to read
Syscall

      WRITE File
mov rax, 01           ; ‘Write' syscall
mov rdi, [fd_in]     ; file Pointer
mov rsi, Buffer      ; Buffer for write
mov rdx, length     ; len of data want to read
Syscall

      DELETE File
mov rax,87
mov rdi,Fname
syscall
      CLOSE File
mov rax,3
mov rdi,[fd_in]
syscall


Assembly Variables
            NASM provides various define directives for reserving storage space for variables. The define Assembler directive is used for allocation of storage space. It can be used to reserve as well as initialize one or more bytes.
Allocating Storage Space for Initialized Data
There are five basic forms of the define directive:
DB - Define Byte (1byte)
DW- Define Word(2 byte)
DD- Define Doubleword(4 byte)
DQ- Define Quadword (8 byte)
DT- Define Ten byte (10 byte)

Allocating Storage Space for Uninitialized Data
            The reserve directives are used for reserving space for uninitialized data. The reserve directives take a single operand that specifies the number of units of space to be reserved. Each define  directive has a related reserve directive.
 There are five basic forms of the reserve directive:
RESB- Reserve a Byte
RESW- Reserve a Word
RESD -Reserve a Doubleword
RESQ -Reserve a Quadword
REST- Reserve a Ten Byte

Instructions needed:
1. MOV-Copies byte or word from specified source to specified destination
2. ROL-Rotates bits of byte or word left , LSB to MSB and to CF
3. AND-AND each bit in a byte or word with corresponding bit in another byte or word
4. INC-Increments specified byte/word by 1
5. DEC-Decrements specified byte/word by 1
6. JNZ-Jumps if not equal to Zero
7. JNC-Jumps if no carry is generated
8. CMP-Compares to specified bytes or words
9. JBE-Jumps if below of equal
10. ADD-Adds specified byte to byte or word to word
11. CALL-Transfers the control from calling program to procedure

Algorithm:-
1. Declare data segment.
2. Declare string variable “pmsg”.
3. Calculate length of “pmsg” in “pmsg_len”
4. Declare variable “nmsg”.
5. Calculate length of “nmsg” in “nmsg_len”.
6. Declare variable “nwline”.
7. Declare array named array of double word valued seven numbers.
8. Declare variable “arrcnt” and initialize it to 7.
9. Declare variable “pcnt” and initialize it to 0.
10. Declare variable “ncnt” and initialize it to 0.
11. Declare extra segment.
12. Declare variable “dispbuff” and initialize it to 2.
13. Declare macro “print” with 2 arguments.
14. Within the macro following steps.
14.a Move 04 into register “eax”.
14.b Move 01 into ebx.
14.c Move first argument of macro into register “ecx”.
14.d Move second argument of macro into “edx”.
14.e Call interrupt 80H.
15. End the macro.
16. Declare code segment.
17. Give the entry point label for assembly program.
18. Point “esi” to first element in “array”.
19. Move “arrcnt” to “ecx” register.
20. Mark label “up1”.
21. Test the 31st bit of memory location pointed by “esi”.
22. Check the value of carry flag and jump if carry flag is not set to label pointed by “pnxt”.
23. Increment the value of “ncnt” by 1.
24. Skip instruction pointed by “pnxt”
25. Increment “pcnt”
26. Increment esi.
27. Increment esi.
28. Check the value of ecx , if it is zero jump to label pointed by “pskip”.
29. Print “pmsg” having size “pmsg_len”.
30. Move “pcnt” to bl register.
31. Call “disp8num” procedure.
32. Print “nmline” variable.
33. Move 01 to eax.
34. Move 00 to ebx.
35. Call interrupt 80H.