1.
I have two 8 bit-registers holding some values. There is no third register which is free. How can I swap them such that no overflows can occur
Show Answer
The answer is: using XOR operation.
a=a^b
b=a^b
a=a^b
Using arithmetic operations isn't allowed to avoid possibilities of overflow.
2.
What are 'near', 'far' and 'huge' pointers?
Show Answer
Near pointers have a size of 2 bytes. They only store the offset of the address the pointer is referencing. An address consisting of only an offset has a range of 0 - 64K bytes starting from the beginning of DGROUP. A near pointer can be incremented and decremented using arithmetic operators (+, -, ++, and --) through the entire address range. Any attempt to increment a near pointer that has a value of 64K (0xffff) will result in a value of 0. This is referred to as wrapping the pointer. A corresponding result can be expected when attempting to decrement a pointer that contains an address of 0, except the result will be 64K instead of 0. In addition to being incremented and decremented, near pointers can be compared to one another using relational operators ( <, >, ==, >= and <=).
Far pointers have a size of 4 bytes. They store both the segment and the offset of the address the pointer is referencing. A far pointer has an address range of 0 - 1M bytes. It is important to understand that an addressing range of 1M does not remove the 640K barrier from the program. It means that the pointer can address the upper memory area (641 - 1M) which typically contains video memory, ROM and anything else that may be loaded high. A far pointer can be incremented and decremented using arithmetic operators. When a far pointer is incremented or decremented ONLY the offset of the pointer is actually incremented or decremented. The segment is never incremented by the arithmetic operators. This means that although a far pointer can address up to 1Mb of memory, it can only be incremented through 64Kb and the offset will start at zero again without changing the value of the segment. This is referred to as "wrapping" the pointer (e.g. 0F3E:FFFF + 1 = 0F3E:0000). When a far pointer is decremented from zero it will wrap the other way and become 64K.
Far pointers are not unique. It is possible to have two far memory addresses that have different segments values and different offset values that address the same memory location e.g. 0777:2222 has an absolute address of 07770 + 2222 = 09992 and 0999:0002 has an absolute address of 09990 + 0002 = 09992. When relational operators are used on far pointers ONLY the offsets are compared. For example: if we let a = 0777:2222 and let b = 0999:0002 then a == b would return false because this is equivalent to 2222 == 0002 which is in fact false. In other words relational operators will only work on far pointers if the segment values of the pointers being compared are the same.
Huge pointers have a size of 4 bytes. They store both the segment and the offset of the address the pointer is referencing. A huge pointer has an address range of 0 - 1M bytes. A huge pointer can be incremented and decremented using arithmetic operators. The only difference between a far pointer and a huge pointer is that a huge pointer is NORMALIZED by the compiler. A normalized pointer is one that has as much of the address as possible in the segment, meaning that the offset is never larger than 15.
A huge pointer is normalized only when pointer arithmetic is performed on it. It is not normalized when an assignment is made. You can cause it to be normalized without changing the value by incrementing and then decrementing it. The offset must be less than 16 because the segment can represent any value greater than or equal to 16 (e.g. Absolute address 0x17 in a normalized form would be 0001:0001. While a far pointer could address the absolute address 0x17 with 0000:0017, this is not a valid huge (normalized) pointer because the offset is greater than 0000F.).
Huge pointers can also be incremented and decremented using arithmetic operators, but since they are normalized they will not wrap like far pointers. Huge pointers can be reliably used with relational operators because they are normalized. This works because normalization of huge pointers insures that every huge pointer is UNIQUE. Huge pointers are never the default pointer, even in the huge memory model.
3.
Garbage Value
Do all variables start with a garbage value? Where does this seemingly random value come from?
Show Answer
No, only uninitialized, local variables start with a garbage value. Global and static variables don't have this problem.
This is because of the fact that the local variables are stored on the local stack of each function. This stack is not purged(cleared) before allocating memory during runtime. This means, whatever value was held in that stack space, stays there, giving us an unpredictable, seemingly random value.
4.
What will be the output of the following code? Justify your answer.
int a[]={10,20,30,40,50};
int i;
for(i=0;i<5;i++)
printf("%d ", i[a]);
Show Answer
Output:
10 20 30 40 50
In C language an array element referenced by its subscript, like
a[i]
is treated as such:
*(a+i)
Similarly, in the program:
i[a]
is treated as:
*(i+a)
Which is the same as before. Hence, the result.
5.
Write an equivalent of the sizeof function using ONLY macros
Show Answer
#define size_of(data) ((char *)(&data +1) - (char *)(&data))
6.
What is BSS Section?
Show Answer
BSS stands for "Block Started by Symbol".
In the object module (the OBJ file) compiled from source code, the bss section contains the static local variables (no functions). Those variables which have non-zero initial values are not stored in BSS.
It also contains the global variables, both extern and static variables that are also initialized to zero. You already know: all global variables are initialized to zero by default.
7.
Suppose I have several pointer pointing to a memory location. If I reallocate that memory, what happens to the other pointers?
Show Answer
The other pointers become useless unless we change them to point to the right location
8.
Pointer Problem
Is it possible to create a pointer to unsingned int? Justify your answer
Show Answer
Of course it is. The pointer is not concerned with the data type of what it is pointing to.
9.
Differentiate between 'Code Portability' and 'Binary Portability'
Show Answer
Code portability means writing such code which can be compiled on another platform, to give the same result(output) without requiring any change to the source code. A C program is code portable, as long as you avoid using platform specific code (eg. using DOS.H only works under DOS/Windows)
Binary portability means that the compiled machine code (executable) can be deployed to any other platform without requiring it to be recompiled from source
10.
Can you implement the fix function without using library routines?
Show Answer
int fix(float n)
{
if(n<0.0)
return n-1;
return n+1;
}