Previous: Operators To the Table of Content Next: Run-time error codes

- 2.3.13 -
TMT Pascal Language Description
Built-in Assembler

Differences between 16- and 32-bit code

While this manual does not really teach 32-bit assembly programming, we will list here several considerations important in 32-bit assembler programming. These considerations may be helpful to a 16-bit programmer entering the 32-bit arena.

Avoid using 16-bit registers for indexation
The built-in assembler will correctly assemble instructions like
  MOV       BX,offset table
  MOV       AX,table[BX]
  JMP       table[BX]
However, these instructions will not work correctly if the size of your program exceeds 64K and the 'table' variable is placed after the 64K limit. This is because 16-bit addresses span only the 64K of the segment. The last example above is the most dangerous; it is likely to crash the system.

Jump tables
Jump tables should be build as tables of 32-bit addresses, not 16-bit addresses.

Longint (32-bit) Arithmetic
Try to use the longint arithmetic as much as possible. 16-bit instructions often take more space than corresponding 32-bit instructions. In
  XOR     AX,    AX
  MOV     data1, AX
  MOV     data2, AX
it would be better to replace the first instruction with
  XOR     EAX, EAX
which is one byte shorter. Furthermore, if data1 and data2 can be changed into longints, you may save a lot more space (and time) both in the assembler and the Pascal sections of the program.

ECX vs CX
Loop and repeat instructions in 32-bit mode use the ECX register rather than CX. The following program segment is likely to cause problems:
  MOV    CX,  size
  MOV    ESI, source
  MOV    EDI, dest
  REP    MOVSB
Also notice that the source and destination registers are ESI and EDI, rather than SI and DI.

POPAD/PUSHAD
Use POPAD and PUSHAD instead of POPA and PUSHA. The latter instructions generate only 16-bit pushes.

POPFD/PUSHFD
Use POPFD and PUSHFD instead of POPF and PUSHF. The latter instructions generate only 16-bit pushes.

IRETD
Use 'IRETD' instead of 'IRET'. The latter instruction pops 16-bit registers.

String instructions
When doing string operations, it is later to use double word instructions instead of byte or word. Use MOVSD instead of MOVSW or MOVSB.

JECXZ vs JCXZ
Distinguish between the JCXZ and JECXZ instructions. The former tests the CX register, while the latter tests ECX. Use of JCXZ instead of JECXZ may lead to hard-to-find bugs. Similarly, LOOP tests ECX, while LOOP16 tests CX.

Function results
Remember to return 32-bit results in EAX, not DX:AX.

ES: preservations
Do not change the ES register. TMT Pascal depends on ES = DS.

Immediate PUSH
TMT Pascal assumes that an immediate push instruction like
   PUSH    Small 0
   PUSH    Small offset data
Furthermore notice that like TASM and unlike the PharLap assembler, TMT Pascal will treat
   PUSH    Word Ptr 0
as if it were
   PUSH    Word Ptr [0]
Var Parameters
Similar to 16-bit mode, Var parameters are 32-bit pointers. However, in TMT Pascal, pointers are just 32-bit offsets within the data segment. Therefore, Var parameters are retrieved with a 'MOV' instruction, not with an LES or an LDS.

Local Symbols
Local Symbols and Parameters are addressed via the EBP register. For example, in
var
  local: Longint;
asm
   MOV   EAX, local
end;
the last line assembles into
   MOV   EAX, [EBP-4]



Previous: Operators To the Table of Content Next: Run-time error codes
Operators Table of Content Run-time error codes

- 2.3.13 -