Aplicaciones Con Lenguaje De Programacion Hibrida

Aplicaciones Con Lenguaje De Programacion Hibrida

Inline Assembler

External Modules

Most high-level languages (3rd-generation) allow the programmer to include object code compiled or assembled in other languages. A good example of this is Turbo Pascal’s ability to use object code modules created from Turbo Assembler. There are various technical issues regarding the linkage of assembler to pascal code but, if the standard assembler directives are used there ought not to be too many glitches.

Of the multitude of items that need to be checked when linking assembler to pascal, the following are most important:

    * the assembler module must be created with the the functions to be exported indicated by a PUBLIC statement
    * the pascal program must contain an external declaration for the procedures to be imported
    * the pascal program must contain a  include directive to include the object code into the program
    * when calling procedures with parameters, the parameters are shifted onto the stack from left to right - take note of this when writing the assembler code
    * return values from functions must be stored in the AX register 

Although some languages (eg. C) allow the programmer to write modules in high-level language and link these to a main program in assembler, this is not possible with Turbo Pascal. It is only possible to write procedures in assembler and link these to pascal, which must contain the main program body.

In order to keep the following examples simple, all parameters and return values are assumed to be of type either byte or word. Turbo Pascal has some advanced features for linking to assembler modules but lots of these are very specific to Turbo Pascal. For further information, consult the Turbo Pascal Reference Manual. Sample Program #17 { program to illustrate simple linking to an ASM file from pascal }

program External Declarations?;

procedure readsint; external; { define readsint as being in another module } procedure writesint; external;{ define writesint as being in another module }

{$L ioasm.obj} { include ioasm module object code }

begin readsint; { read in a value into AX } writesint; { output the value in AX } end. Sample Program #18 - assembler part ; sample function to return a value




PUBLIC samplefunc ; declare that samplefunc is to be used in other ; modules

samplefunc PROC ; stores a specific integer value into AX mov ax,1234 ret samplefunc ENDP

END Sample Program #18 - pascal part { program to illustrate linking to a function in an ASM file from pascal }

program External Declarations;

function samplefunc : word; external; { define samplefunc as being in another module }

{$L sample18.obj} { include sample18 module object code }


writeln (‘The value is : ‘, samplefunc);

{ output return value from ASM module }


Machine Code

Another option to programmers was to include machine code directly into the pascal program. By means of the INLINE command, the programmer could specify a string of machine code commands to be integrated with the compiled code at that point. This is not the option of choice since it means that the programmer has to convert the assembly language commands into machine code manually and enter the binary data into the pascal source file. This method is almost never used nowadays. Inline assembler The more recent versions of the Turbo Pascal compiler introduced a built-in assembler in the IDE. This means that a programmer can write parts of the pascal program directly in assembly language. The inline assembler, as it is called, can access all variables used in the program. Procedures can even be declared as strictly assembler, thereby eliminating the redundant startup and cleanup code that pascal might normally add.

Just as a block of pascal code is defined by a begin and end, a block of inline assembler code is defined by an asm and end. Strict assembly language procedures are declared to be assembler at the end of the procedure/function declaration. There are of course certain points that must be noted:

    * most of the directives do not work - primarily because they are not needed
    * in procedures, no stack setup is required and no RET is needed
    * comments are in standard pascal-style {}
    * the data segment is already set up and must not be redirected
    * function return values must be set in AX 

Sample Program #19 { program to illustrate inline assembler functionality }

program Inline Demo?;

var Equip : word;

begin asm { assembler statements } int 11h { get equipment list } mov Equip,ax { save in variable Equip } end; Writeln (‘The equipment word for this computer is : ‘, Equip); end. Sample Program #20 { program to illustrate memory access functionality }

program Memory Demo?;

var Equip : word;

begin Equip:=Mem W?[$0040:$0010]; { get equipment list from BIOS Data Area } Writeln (‘The equipment word for this computer is : ‘, Equip); end. Sample Program #21 { program to illustrate inline assembler procedures functionality }

program Inline Demo;

const Video Segment? = $B800; { assume C/E/VGA mode }

procedure Clr Scr; assembler; { procedure to clear the screen } asm mov ax,Video Segment { set the video segment } mov es,ax mov cx,25*80 { get number of characters on screen } xor bx,bx { set start position on screen } @@1: mov byte ptr es:[bx],0 { clear character } add bx,2 { move to next position } loop @@1 end;

procedure Goto XY ( x, y : byte ); assembler; { procedure to move the cursor to the specified coordinates } asm mov dh,y { set DH=y-1 } dec dh mov dl,x { set DL=x-1 } dec dl mov bh,0 { set page number=0 } mov ah,2 { set service number } int 10h { call video interrupt } end;

function Get Character? ( x, y : word ) : byte; assembler; { procedure to return the character at a certain position on the screen } asm mov ax,y { y } dec ax { y-1 } mov dx,160 mul dx { 160*(y-1) } mov bx,x { x } dec bx { x-1 } shl bx,1 { 2*(x-1) } add bx,ax { BX=160*(y-1) + 2*(x-1) } mov ax,Video Segment { set ES to video segment } mov es,ax mov ax,es:[bx] { get character } end;

begin Clr Scr; { clear screen } Goto XY (10, 10); { move cursor } Writeln (‘X’); { output X at 10,10 } Writeln (Chr (Get Character (10, 10))); { get/output the character at 10,10 } end.

Mis sitios nuevos:
Politica de Privacidad