SIZE MISMATCH ERRORS

Posted by Atezaz | 6:39 PM | | 0 comments »

If we change the directive in the last example from DW to DB, the program will still assemble and debug without errors, however the results will not be the same as expected. When the first operand is read 0A05 will be read in the register which was actually two operands place in consecutive byte memory locations. The second number will be read as 000F which is the zero byte of num4 appended to the 15 of num3. The third number will be junk depending on the current state of the machine. According to our data declaration the third number should be at 0114 but it is accessed at 011D calculated with word offsets. This is a logical error of the program. To keep the declarations and their access synchronized is the responsibility of the programmer and not the assembler. The assembler allows the programmer to do everything he wants to do, and that can possibly run on the processor. The assembler only keeps us from writing illegal instructions which the processor cannot execute. This is the difference between a syntax error and a logic error. So the assembler and debugger have both done what we asked them to do but the programmer asked them to do the wrong chore.

The programmer is responsible for accessing the data as word if it was declared as a word and accessing it as a byte if it was declared as a byte. The word case is shown in lot of previous examples. If however the intent is to treat it as a byte the following code shows the appropriate way.

Example 2.5

001 ; a program to add three numbers using byte variables
002 [org 0x0100]
003 mov al, [num1] ; load first number in al
004 mov bl, [num1+1] ; load second number in bl
005 add al, bl ; accumulate sum in al
006 mov bl, [num1+2] ; load third number in bl
007 add al, bl ; accumulate sum in al
008 mov [num1+3], al ; store sum at num1+3
009
010 mov ax, 0x4c00 ; terminate program
011 int 0x21
012
013 num1: db 5, 10, 15, 0

3 The number is read in AL register which is a byte register since the memory location read is also of byte size.

5 The second number is now placed at num1+1 instead of num1+2 because of byte offsets.

26


13 To declare data db is used instead of dw so that each data declared occupies one byte only.

Inside the debugger we observe that the AL register takes appropriate values and the sum is calculated and stored in num1+3. This time there is no alignment or synchronization error. The key thing to understand here is that the processor does not match defines to accesses. It is the programmer’s responsibility. In general assembly language gives a lot of power to the programmer but power comes with responsibility. Assembly language programming is not a difficult task but a responsible one.

In the above examples, the processor knew the size of the data movement operation from the size of the register involved, for example in “mov ax, [num1]” memory can be accessed as byte or as word, it has no hard and fast size, but the AX register tells that this operation has to be a word operation. Similarly in “mov al, [num1]” the AL register tells that this operation has to be a byte operation. However in “mov ax, bl” the AX register tells that the operation has to be a word operation while BL tells that this has to be a byte operation. The assembler will declare that this is an illegal instruction. A 5Kg bag cannot fit inside a 1Kg bag and according to Intel a 1Kg cannot also fit in a 5Kg bag. They must match in size. The instruction “mov [num1], [num2]” is illegal as previously discussed not because of data movement size but because memory to memory moves are not allowed at all.

The instruction “mov [num1], 5” is legal but there is no way for the processor to know the data movement size in this operation. The variable num1 can be treated as a byte or as a word and similarly 5 can be treated as a byte or as a word. Such instructions are declared ambiguous by the assembler. The assembler has no way to guess the intent of the programmer as it previously did using the size of the register involved but there is no register involved this time. And memory is a linear array and label is an address in it. There is no size associated with a label. Therefore to resolve its ambiguity we clearly tell our intent to the assembler in one of the following ways.

mov byte [num1], 5 mov word [num1], 5

0 comments