Showing posts with label program. Show all posts
Showing posts with label program. Show all posts

Sunday, January 12, 2014

Printing a String using x86 assembly under MASM/TASM


String is an array of character, where all character are stored in contiguous fashion. In computer's view, string is an array of bytes stored in contiguous memory. Here, I have used term 'byte' because computer does not recognize integer and character separately. It knows only bytes. 

 
To print a string, we need an array of bytes or character stored in a memory with a 'end of string' character. Let's see how it is done.
Generally,the array are stored in a data segment.For example, 
 
    .data
             char db 'a','b','c','d','$'

Here, 'char' is the name of array variable. These characters will get stored in contiguous memory locations with values 'abcd'. The '$' is end of string character. It recognizes that there are no more characters after it. It is compulsory to have '$' as the end of string characters for all strings. As I already told, computer only knows bytes, following declaration of string is also similar to previous one.

    .data
    char db 41,42,43,44,'$'

Here, 41, 42, 43 & 44 are ASCII values of 'abcd' respectively. In order to print a string on screen x86 architecture uses DOS interrupt number 21H with function number 09H. So,

    INT 21H & AH=09H

will do the task for us.
Before this, we must store offset address/effective address of the string in data register (DX). Address of string or address of first character of string must be stored in DX register, function 09H gets this address from DX and print the characters on the screen from first byte till '$'.
Following code will print 'welcome' on screen.

.DATA
      MESSAGE DB 'WELCOME$'

.CODE
     MOV DX, @DATA
     MOV DS, AX
     LEA DX, MESSAGE
     MOV AH, 09H
     INT 21H

  MOV AH, 4CH
  INT 21H
END

The instruction 'LEA' loads the offset of effective address of variable 'MESSAGE' in DX register. Remember, it is mandatory to have '$' at the end!
You may try by removing '$' from the string.

Monday, January 6, 2014

Print a number using Assembly Language


Let's see something simple but interesting stuff in assembly language. To print a value on screen, various high level programming languages use there library function and statement. For example, C uses 'printf', C++ uses 'cout', Java uses 'println' and Python uses 'print'. It is single line statements that does our task. But, microprocessor implements several sequential steps to print a number on screen. 
 

Here, I have used the widely used MASM to demonstrate this work. Basically, to print a number microprocessor don't have any function for this. It is only possible to print a single character with function number 02 an interrupt number 21h. The character that you have to print, must be present in DL register.
For example,

MOV DL,'a'
MOV AH,02H
INT 21H

This code will print 'a' on the screen (without quote!). Here DL register of processor is storing ASCII value of character 'a'. So, following code will also do the same task, as ASCII value of character 'a' is 41 in hexadecimal.
 
MOV DL,41H
MOV AH,02H
INT 21H

Here, 02 is function number and it is necessary to store it in AH register before invoking an interrupt. Now, to print number on screen it is not directly possible using assembly language. We need to do it using ASCII values of hexadecimal digit. Remember ASCII values of 0 to 9 are 30 to 39 respectively. So, if you want to print 5 on screen, we need to store 35 in DL register before invoking the interrupt. Now, following code will print 5 on screen.
 
MOV DL,35H
MOV AH,02H
INT 21H

It means that, we need code conversion by adding 30 in hex to the respective single digit number. If you want to print 2 digit number the same procedure can be followed for both digit by rotating. Then one after the another following algorithm will do the task for us.
  1. Get a two digit number in temporary register say BH.
  2. Rotate the bits of the number by 4 position so hex digit would be swapped.
  3. Copy the rotated number in DL register.
  4. Mask high order 4 bits to zero.
  5. Add 30h in DL.
  6. Use function 02h and int 21h to print the number.
  7. Repeat the steps 2 to 6 for second digit also.
Code:
  1. MOV BH,96H ;number to print
  2. MOV CH,02H ;number of digits
  3. MOV CL,04H ;rotation count
  4. UP:ROL BH,CL ;swap digits
  5. MOV DL,BH
  6. AND DL,0FH ;mask MSB digit
  7. ADD DL,30H ;add 30 in DL
  8. MOV AH,02H ;function number
  9. INT 21H
  10. DEC CH ;do twice
  11. JNZ UP
Here, we simulate the code stepwise.
  1. BH=96H
  2. CH=02H
  3. CL=04H
  4. BH=69H
  5. DL=69H
  6. DL=09H
  7. DL=39H
  8. AH=02H
  9. It will print DL=39 i.e 9 on screen.
  10. CH=01H
  11. Condition true as ZF=0. Jump to 4th Statement.
  1. BH=96H
  2. DL=96H
  3. DL=06H
  4. DL=36H
  5. AH=02H
  6. It will print DL=36 i.e 6 on screen.
  7. CH=00H
  8. Condition false so terminate.
Now, here we have printed the hex digits only between 0-9. But, if digits are between A-F then we need to check this condition also. The ASCII value of numbers and characters have difference of 07H. So, if the hex digit of number is greater than 9 then to have to add 07H also in DL register. The following code will do the task.
 
MOV BH,5CH ;number to print
MOV CH,02H
MOV CL,04H
UP:
ROL BH,CL
MOV DL,BH
AND DL,0FH
CMP DL,09H
JBE NEXT
ADD DL,07H
NEXT:
ADD DL,30H
MOV AH,02H
INT 21H
DEC CH
JNZ UP

You may use debugger to check the execution of the code. It is to be noted that this code will work in x86 architecture using MASM or TASM.

Sunday, January 5, 2014

Input in Assembly Language Programming


You must think of function 'scanf' first. How simple it is! This C function reads the data from keyboard. As it is high level language function, it is very simple to understand. But, behind the scenes a lot many forces are active to make this 'scanf' function very successful! This all procedures can be seen in an assembly language program. When you want to read something from keyboard using microprocessor's programming language, it gives real demonstration of input procedures of computing. Lets see how it does it. I am writing the procedure here from DOS point of view. 

 
Most of processor's operations are based on interrupt. To read the data from keyboard, we need to invoke an interrupt! The DOS interrupt whose number is 21 in hexadecimal is required to accomplish this operation. An interrupt of computer needs the function number also. Now, to read a character DOS 21H interrupt needs function number 01. This function number must get stored into AH register of the processor.
The function number 01 an interrupt 21H is used to read a character from keyboard. So reading a character is so simple.

MOV AH,01H
INT 21H

This code reads a character from keyboard and processor immediately switches to next statement. The character which was pressed by user on keyboard will be stored in AL register! It usually stores the ASCII value of character pressed. In short, this function acts as getche() function if C. For example, if user pressed 'a' on keyboard then the value of AL will be 41 in hexadecimal! Now, how to read a 2 or 4 digit hex number, becomes a critical problem.

In this case, we may follow the following procedure for two digit number.
  1. Read the first digit number as a character.
  2. As the ASCII values of numbers and actual number has difference of 30, subtract 30 from AL For example, ASCII of 5 is 35.
  3. Swap the digits of two digit hex value in AL register. For example, AL=05 will become 50.
  4. Store this value in some other register such as BL.
  5. For reading second digit of the number, follow step 1 and 2 and finally add contents of AL and BL. Then we will get actual number that we read.

The following code will do the task for achieving this two digit number input.

1. MOV AH,01H
2. INT 21H ;reads first digit
3.
4. MOV BL,AL
5. SUB BL,30H
6. MOV CL,04H
7. ROL BL,CL
8.
9. MOV AH,01H
10. INT 21H ;reads second digit
11.
12. SUB AL,30H
13. ADD AL,BL ;AL will have number

For example, user entered 75 from keyboard then,
4. BL=37H
5. BL=07H
6. CL=04H
7. BL=70H
10. AL=35H
12. AL=05H
13. AL=75H ;AL with final value.

The code will work for digit entered between 0 to 9 only.

The hex number entered will be greater than 09H also. When user enters any hex digit between A to F then we have to add one more step in algorithm. In such case subtract the input value in AL by 07H also. Because the ASCII value difference between numerical value and character value is 07! So compare the value is below or equal to 09. For this, the conditional jump JBE/JNA can be used. Following code will do the task.

MOV AH,01H
INT 21H
MOV BL,AL
CMP BL,39H
JBE NEXT1

SUB BL,07H
NEXT1:
SUB BL,30H
MOV CL,04H
ROL BL,CL
MOV AL,01H
INT 21H
CMP AL,39H
JBE NEXT2
SUB AL,07H
NEXT2:
SUB AL,30H
MOV CL,04H
ADD AL,DL

Note: All the values used in this article are in hexadecimal form. It will work for x86 programming using MASM/TASM.

Sunday, September 29, 2013

C Program to find the floating point IEEE 754 representation

A computer can use only two kinds of values. That is, fixed point and floating point. The fixed point values are stored in the computer memory in binary format representing their ASCII value.
For example:-
Character ‘A’ can be stored as- 1000001. Because, 65 is ASCII value of ‘a’. In case of floating point values, these follow the IEEE 754 standard to store in memory. Whenever any programming language declared- float a; Then the variable 'a's value will be stored in memory by following IEEE 754 standard.
This standard specifies the single precision and double precision format. In case of C, C++ and Java, float and double data types specify the single and double precision which requires 32 bits (4-bytes) and 64 bits (8-bytes) respectively to store the data.
Lets have a look at these precision formats.
Single Precision:-
It requires 32 bit to store. Following is the format of single precision.
In order to store a float value in computer memory, a specified algorithm is followed.
Take an example at float value- 3948.125
  1. Covert 3948 to binary. i.e. 111101101100
  2. Convert .125 to binary,
         0.125 x 2 = 0.25    0
         0.25 x 2 = 0.5        0
        0.5 x 2 = 1             1
            = 0.001
Now 3948.125 = 111101101100.001
  1. Normalize the number so that the decimal point will be placed after MSB-1. i.e.
111101101100.001 = 1.11101101100001 x 211
  1. Now, for this number s=0, as the number is positive.
Exponent' = 11 and
Mantissa = 11101101100001
  1. Bias for single precision used is 127 so,
Final exponent = exponent' + 127 i.e.
E= 11 + 127= 138 = 10001010 in binary.
  1. Final value-


In this format the number 3948.125 will be stored in main memory.

For double precision values following changes are expected:
Total bits required – 64
Exponent – 11 bits
Mantissa – 52 bits
Bias value – 1023
Now, if you want to find the IEEE 754 representation at any floating point number, following program can be used.

#include<stdio.h>
int binary(int n, int i)
{
    int k;
    for (i--; i >= 0; i--)
   {
      k = n >> i;
      if (k & 1)
          printf("1");
      else
         printf("0");
    }
}
typedef union
{
      float f;
      struct
      {
            unsigned int mantissa : 23;
            unsigned int exponent : 8;
            unsigned int sign : 1;
       } field;
} myfloat;
int main()
{
           myfloat var;
    printf("Enter any float number: ");
           scanf("%f",&var.f);
           printf("%d ",var.field.sign);
           binary(var.field.exponent, 8);
           printf(" ");
           binary(var.field.mantissa, 23);
           printf("\n");
           return 0;
}
Explanation-
The function binary( ) is used to convert the number ‘n’ into binary format and print its ‘i’ number of bits.
In C, structure members can be specified with no. of bits with size. It is known as bit fields. As ‘float f’ is declared in ‘union myfloat’. It can use 23 bits to store mantissa exponent can use 8 and sign can use one! The variable ‘var’ is at myfloat type. So, in order to access mantissa, we can use ‘var.field. mantissa’. Here, mantissa is the name of internal structure. So, float value’s internal bits can be accessed bitwise with sign, exponent and mantissa separately.
Run the program and see the output of the said example!