PoiNtEr->: computer science

                             Difference between a dream and an aim. A dream requires soundless sleep, whereas an aim requires sleepless efforts.

Search This Blog

Showing posts with label computer science. Show all posts
Showing posts with label computer science. Show all posts

Monday, April 16, 2012

Inline-Assembly


We can instruct the compiler to insert the code of a function into the code of its callers, to the point where actually the call is to be made. Such functions are inline functions. Sounds similar to a Macro? Indeed there are similarities.
What is the benefit of inline functions?
This method of inlining reduces the function-call overhead. And if any of the actual argument values are constant, their known values may permit simplifications at compile time so that not all of the inline function’s code needs to be included. The effect on code size is less predictable, it depends on the particular case. To declare an inline function, we’ve to use the keyword inline in its declaration.
Inline assembly is important primarily because of its ability to operate and make its output visible on C variables. Because of this capability, "asm" works as an interface between the assembly instructions and the "C" program that contains it.
Programming Languages 


There are some things to note when using inline assembler in C program, firstly, most of C compiler uses the AT&T format, not the Intel format that most people are used to. In the AT&T format, the operands are reversed. If you use a register as an operand, prefix it with % and immediate values get a $. You also have to add a suffix to the instructions to specify the size of the operands.
movl %ecx, %ebx
Notice the 'l' at the end of mov. This specifies that the instruction is working on 32 bit operands. 'w' indicates that the instruction is using 16 bit operands and 'b' for 8 bit.
So, with all that under your belt, how do you actually add it into your code? You use the asm keyword. It takes the following form.
asm("instructions" : outputs : inputs : clobber list);
You don't actually need to use the last three, but for longer code you will need them. Let's see what they do.
asm volatile("
 pushl %%eax
 movl %1, %%eax
 movl %2, %%ebx
 addl %%ebx, %%eax
 movl %%eax, %0
 popl %%eax"
 : "=g" (i)
 : "g" (j), "g" (k)
 : "bx" );
Wow. Let's go through that piece of code step by step. The actual code, as you can probably figure out, adds j and k and puts the output in i. Firstly, what's with the '%%'? If you have any inputs or outputs, then you must put %% before your register names. Next up, the input list. Who is 'g'? G simply tells the compiler to put the argument anywhere. You can then reference them in order, %0 is i, %1 is j and %2 is k. '=g' tells the compiler that it is output. We put ebx into the clobbered list because it gets clobbered.


Clobber List



Some instructions clobber some hardware registers. We have to list those registers in the clobber-list, ie the field after the third ’:’ in the asm function. This is to inform gcc that we will use and modify them ourselves. So gcc will not assume that the values it loads into these registers will be valid. We shoudn’t list the input and output registers in this list. Because, gcc knows that "asm" uses them (because they are specified explicitly as constraints). If the instructions use any other registers, implicitly or explicitly (and the registers are not present either in input or in the output constraint list), then those registers have to be specified in the clobbered list.

Volatile ...?


If you are familiar with kernel sources or some beautiful code like that, you must have seen many functions declared as volatile or __volatile__ which follows an asm or __asm__. I mentioned earlier about the keywords asm and __asm__. So what is this volatile?
If our assembly statement must execute where we put it, (i.e. must not be moved out of a loop as an optimization), put the keyword volatile after asm and before the ()’s. So to keep it from moving, deleting and all, we declare it as
asm volatile ( ... : ... : ... : ...);
Use __volatile__ when we have to be verymuch careful.
If our assembly is just for doing some calculations and doesn’t have any side effects, it’s better not to use the keyword volatile. Avoiding it helps gcc in optimizing the code and making it more beautiful.

Example C Program:

//make value of b equal to value of a
#include<stdio.h>
int main(int argc,char *argv)
{
 int a=10, b;
asm volatile("movl %1, %%eax;movl %%eax, %0;":"=r"(b):"r"(a) :"%eax" );       
printf("%d\n",b);
}


Friday, March 2, 2012

BSS Section in Process Structure

Global variable's life time is until the completion of the program. But what is the point of having two sections for global variables based on initialized and uninitialized. The point is to reduce the executable size of the program before going to discuss about the BSS section we need to understand what process structure, and how the structure looks in the memory (RAM) at the time of execution.


Program Memory Layout

If we are not initialized the global variables the loader will take care to initialize all global variables to zero (0). The loader is designed in such a way to initialize the global to zero while loading the process into RAM. If we are keeping initialized and uninitialized variable in the same block loader will initialize to zero for all the initialized variables too. Compiler developer decided to divide the global sectioninto two parts

1. DATA
2. .BSS

All initialized variable will go to DATA section, this will be decided in compilation time itself. But uninitialized variable will go into BSS section. This block will be created at the time of loading so it reduces the executable size of the program.


Now lets try out some example to proof how bss is effective save memory....

#include<stdio.h>
int a[10000000];
main()
{
long i;
for(i=0;i<10000000;i++)
printf("%d",a[i]);
}
//save it as bss.c
compile above program
>gcc -o bss bss.c
>ls -l bss
output:
-rwxr-xr-x 1 vishal vishal 7149 2012-03-02 19:44 bss
so size of this executable is 7149= around 7KB



#include<stdio.h>
int a[10000000]={1};
main()
{
long i;
for(i=0;i<10000000;i++)
printf("%d",a[i]);
}
//save it as ubss.c
>gcc -o ubss ubss.c
>ls -l ubss
output:-rwxr-xr-x 1 vishal vishal 40007193 2012-03-02 19:50 ubss
size of this executable is :40MB
because here a[] is initialized and memory is already allotted to it...

Friday, February 10, 2012

Flip-Flops...SR,JK,D,T

There are basically four main types of flip-flops: SR, D, JK, and T. The major differences in these flip-flop types are in the number of inputs they have and how they change state. Each type can have different variations such as active high or low inputs, whether they change state at the rising or falling edge of the clock signal, and whether they have asynchronous inputs or not. The flip-flops can be described fully and uniquely by the table given below.
Flip-Flop
Type

Wednesday, February 8, 2012

System Programming In C

To do system programming its very important to have a deep knowledge how we can manipulate register values directly . Every thing on computer like colorful GUI,rock music,etc ends up in 10101010 stored in some register,that is what computer world is all about.
So lets have look on some of important data structure which help us dealing with register values directly.
In the header file dos.h there are two important structures and union (Remember this structure)

1. struct BYTEREGS {
unsigned char al, ah, bl, bh;
unsigned char cl, ch, dl, dh;
};

2. struct WORDREGS {
unsigned int ax, bx, cx, dx;
unsigned int si, di, cflag, flags;
};

3. union REGS {
struct WORDREGS x;
struct BYTEREGS h;
};

There is function int86() which has been defined in dos.h header file. It is general 8086 software interrupt interface. It will better to explain it by an example.



 c program to display mouse pointer

#include<stdio.h>
#include<dos.h>
void main()
{
union REGS i,o;
i.x.ax=1;
int86(0x33,&i,&o);
getch();
}


Interrupt table for c programming language

Interrupt table
List of interrupt numbers and its use



Input
Output
Service No
Use

Interrupt No: 0X33 Use: Mouse
ax

1
Show mouse pointer
ax

2
Hide mouse pointer
ax

0
Initialize mouse

ax
0

ax

7
X co-ordinate restriction
cx

X1 co-ordinate

dx

Y1 co-ordinate

ax

8
Y co-ordinate restriction
cx

X2 co-ordinate

dx

Y2 co-ordinate

ax

3
Get mouse position

bx
Button


cx
X position


dx
Y position

ax

4
Set mouse position
cx

X co-ordinate

dx

Y co-ordinate

ax

5

bx

B=0 left



B=1 right



B=2 center


ax
Button status


bx
Button press counter


cx
X co-ordinate


dx
Y co-ordinate

ax

9
Set graphics pointer shape
bx

Hot spot offset from left

cx

Hot spot offset from right

es:dx

Segment: offset

ax

0XA
Set text pointer type
bx

Pointer type



0-soft type



1-Hardware

cx

Starting line number

dx

Ending line
number


Interrupt no: 0X10 Use: Monitor
ah

2
Positioning cursor
dh

row no

dl

Column no

bh

Page no

ah

6
Clear screen
al

0 to clear
N line to scroll
ch

St.row

cl

St column

dh

End row

dl

End column

bh

Col

ah

6
Scroll window l line up
al

1

bh

Color

ch

St row

cl

St column

dh

End row

dl

End column

ah

8
Read a character from screen
bh

Page



Ah

ah

9
Write a char on a screen
bh

Page



Ah

ah

0
Set video mode
al

0x13
Switch to 320 X 200 and 256 color graphics mode

Ch
0x12
Switch to 640X480 and 16 color graphics mode

Cl
0x11
Switch to 640X480 and 2 color graphics mode

Dh
0x3
Switch to 25X80 and 16 color test mode

dl
0x1
Switch to 40X25 and 16 color text mode
ah

0x2
Switch to 80X25 and 16 color text mode
bh

3
Get cursor position


Page number



Starting line for cursor



Ending line for cursor



Row position



Col position



Page number

ah



bh




Interrupt No: 0X1A Use: Time


2
Get Time
Ah
Ch
Hours


Cl
Minutes


Dh
Second


Dl
Daylight-saving



Time code

Ah

3
Set time
Ch

Hours

Cl

Minutes

Dh

Second

Dl

Daylight-time

ah

4
Get date

Ch
Century


Cl
Years


Dh
Month


dl
day

Ah

5
Set date
Ch

Century

Cl

Year

Dh

Month

dl

day


Interrupt No: 0X16 Use: Key Board
Ah

0
Get the scan code

Ah



al

Get ascii code





Interrupt No: 0X21 Use: Miscellaneous
Ah

1
Echo input character on screen

al
Data

Ah

2
Character output
Dl

Character

Ah

5
Pinter output
Dl

Character

Ah

9
Display string
Ds:dx

String

Ah

0XE
Select disk
Dl

Drive no

Ah

0XF
Open file
Ds:dx

File control

Ah

0X10
Close file
Ds:dx

File control

Ah

0X11
Find first file
Ds:dx

File control

Ah

0X12
Find next file
Ds:dx

File control

Ah

0x13
Delete file
Ds:dx

File control

Ah

Ox16
Create file
Ds:dx

File control

Ah

0x17
Renaming file
Ds:sx

Special file control

Ah

0x19
Get current disk

Al


Ah

Drive number

Ds:dx

0x23
Get file size


File control

Al
ah
0x25
Set interrupt
Ds:dx

New function

Ah

0x35
Get interrupt vector
Al

Interrupt no



Interrupt handler

Ah

0x39
Create a directory
Ds:dx

Directory name

Ah

0x3A
Delete directory
Ds:dx

Directory name

Ah

0X3B
Set current directory
Ds:dx

Directory name







in the WORDREGS

struct WORDREGS {
unsigned int ax, bx, cx, dx;
unsigned int si, di, cflag, flags;
};

And WORDRGS is define in the union REGS

union REGS {
struct WORDREGS x;
struct BYTEREGS h;
};

So to access the ax first declare a variable of REGS that is

REGS i,o;

To access the ax write i.x.ax (We are using structure variable i because ax is input, see interrupt table).
So, to display mouse pointer assign the value of service number:

i.x.ax=1;

To pass the information to microprocessor we use int86 function. It has three parameters

1. Interrupt number i.e. 0x33
2. union REGS *inputregiste i.e. &i
3. union REGS *outputregiste i.e. &o;

So write: int86 (0x33, &i, &o);



Now lets see how we can write value to a specific port.Dealing with port become very important when we want to interface some new device with our regular device.
Its similar to saying we have to give new interface card order  in language which the new device understands.The ports here are medium through which we communicate .We give orders to the ports (generally predefined) and they follow.

The following set of functions will do the task pretty well,

inport reads a word from a hardware port.
inportb reads a byte from a hardware port.
outport outputs a word to a hardware port.
outportb outputs a byte to a hardware port.


INPORT is used for word by word reception. The syntax is as follows:

inport (portid);

here portid is the address of the port. For parallel port the address is 0x378. For example

int result;
result=inport( 0x378 );

this will read the word of data from the parallel port and will be stored in the variable result.

INPORTB is used for byte by byte reception. The syntax is as follows:

inportb (portid)

For example

unsigned char result;
result = inportb(0x378);

this will read a byte from the port and will be saved in the variable result.

OUTPORT is used to output a word to the port. The syntax is as follows:

outport (portid,value);

here value is the data for output. For example

int value =450;
outport(0x378,value);

this will output the data 450 to the parallel port.

OUTPORTB is used to output a single byte to a port. The sysntax is as follows:

outportb (portid, value);

For example

outportb (0x378,255);


List of VGA ports and register name


Register name port index mode 3h (80x25 text mode) mode 12h (640x480 planar 16-bit color mode) mode 13h (320x200 linear 256-color mode) mode X (320x240 planar 256 color mode)
Mode Control 0x3C0 0x10 0x0C 0x01 0x41 0x41
Overscan Register 0x3C0 0x11 0x00 0x00 0x00 0x00
Color Plane Enable 0x3C0 0x12 0x0F 0x0F 0x0F 0x0F
Horizontal Panning 0x3C0 0x13 0x08 0x00 0x00 0x00
Color Select 0x3C0 0x14 0x00 0x00 0x00 0x00
Miscellaneous Output Register 0x3C2 N/A 0x67 0xE3 0x63 0xE3
Clock Mode Register 0x3C4 0x01 0x00 0x01 0x01 0x01
Character select 0x3C4 0x03 0x00 0x00 0x00 0x00
Memory Mode Register 0x3C4 0x04 0x07 0x02 0x0E 0x06
Mode Register 0x3CE 0x05 0x10 0x00 0x40 0x40
Miscellaneous Register 0x3CE 0x06 0x0E 0x05 0x05 0x05
Horizontal Total 0x3D4 0x00 0x5F 0x5F 0x5F 0x5F
Horizontal Display Enable End 0x3D4 0x01 0x4F 0x4F 0x4F 0x4F
Horizontal Blank Start 0x3D4 0x02 0x50 0x50 0x50 0x50
Horizontal Blank End 0x3D4 0x03 0x82 0x82 0x82 0x82
Horizontal Retrace Start 0x3D4 0x04 0x55 0x54 0x54 0x54
Horizontal Retrace End 0x3D4 0x05 0x81 0x80 0x80 0x80
Vertical Total 0x3D4 0x06 0xBF 0x0B 0xBF 0x0D
Overflow Register 0x3D4 0x07 0x1F 0x3E 0x1F 0x3E
Preset row scan 0x3D4 0x08 0x00 0x00 0x00 0x00
Maximum Scan Line 0x3D4 0x09 0x4F 0x40 0x41 0x41
Vertical Retrace Start 0x3D4 0x10 0x9C 0xEA 0x9C 0xEA
Vertical Retrace End 0x3D4 0x11 0x8E 0x8C 0x8E 0xAC
Vertical Display Enable End 0x3D4 0x12 0x8F 0xDF 0x8F 0xDF
Logical Width 0x3D4 0x13 0x28 0x28 0x28 0x28
Underline Location 0x3D4 0x14 0x1F 0x00 0x40 0x00
Vertical Blank Start 0x3D4 0x15 0x96 0xE7 0x96 0xE7
Vertical Blank End 0x3D4 0x16 0xB9 0x04 0xB9 0x06
Mode Control 0x3D4 0x17 0xA3 0xE3 0xA3 0xE3

Reference:c-pointer
                 osdev