[<<Previous Entry]
[^^Up^^]
[Next Entry>>]
[Menu]
[About The Guide]
INLINE Inline Assembler Code pp 211
Syntax: Inline (Code Elements) ;
Type: N/A
Form: Procedure or Function
Purpose: Insert machine language code into the instruction stream.
Notes: An inline statement consists of the word Inline followed by one
or more code elements separated by slashes and enclosed in
parentheses. Code elements are constructed of data elements.
A data element is either an integer constant, a variable, function,
or procedure identifier, or a location counter reference.
The value assigned to these is that of their offset in memory, or
for the location counter, its current value.
A code element is built from one or more data elements and
separated by plus (+) or minus (-) signs.
A code element generates a byte or word of code. The value of the
code is calculated by adding or subtracting the values of the
data elements according to the signs that separate them.
Constants exist in the code segment.
Global variables exist in the data segment.
Local variables and procedure parameters exist on the stack.
Example: Inline (10 / $2345 / Count+1 / (Sort-*) + 2) ;
A code element will generate one byte of code if it consists of
integer constants only, and if its value is within the 8 bit
range of 0..$FF. If the value is outside this range or if the
code element refers to a variable, procedure, function, or location
counter then a word of code is generated.
The < and > characters may be used to overrid the automatic
size selection described above. If a code element starts with a <
character, only the least significant byte of the value is coded.
If an element starts with > then a word value is always coded.
Example: Inline (<$1234/>$44) ; results in $34, $44, $00
Global variables are accessible via the DS register, whereas local
variables such as those declared locally in a sub program are
relative via the BP register in the stack segment.
Typed constants, functions, and procedures are all relative to
the code segment CS register.
Inline should not attempt to access variables not within the
current scope. Global variables and those declared within the
current subprogram are the current scope. Other local variables
only exist on the stack during the time that their parent sub
program has control.
Inline statements may be freely mixed throughout the statement
part of the block, and may use all CPU registers.
BP,SP,DS,SS registers must be the same on exit as at entry.
Stack: VAR parameters are passed as Offset:Segment addresses.
Parameters are pushed on the stack from left to right. The
last parm will be at the lowest stack address.
Procedure Test (VAR parm1, parm2, parm3 : Integer) ;
Stack image at entry to INLINE code after PUSH BP:
[BP + 08h] ; Offset of last parm (parm3 here)
[BP + 0Ah] ; Segment of last parm (parm3 here)
[BP + 0Ch] ; Offset of parm2
[BP + 0Eh] ; Segment of parm2
[BP + 10h] ; Offset of parm1
[BP + 12h] ; Segment of parm1
Push BP ; Must save BP entry value
Mov BP,SP ; Set BP to address the stack
Mov AX,[BP + 08h] ; Offset of parm3 (or last parm)
Mov DS,[BP + 0Ah] ; Segment of parm3 (or last parm)
Lds AX,[BP + 08h] ; Load DS,AX with parm3 segment:offset
Lds BX,[BP + 0Ch] ; Load DS,BX with parm2 segment:offset
Lds CX,[BP + 10h] ; Load DS,CX with parm1 segment:offset
VALUE parameters are passed in their entirety except for
arrays and records, which as passed as Offset:Segment addresses.
2 bytes - Integers, Booleans, Chars
Byte values have zero in the most significant byte.
4 bytes - Pointers, Arrays, Records
Passed as Offset:Segment double word
6 bytes - Reals
x bytes - Strings - first byte is string length and the
remaining byte(s) are the string data.
32 bytes - Sets
Usage:
This example converts a string to upper case
VAR
Str : String [255] ; { String to convert to upper case }
BEGIN
Inline
(
$C4 / $BE / Str / { Les DI,Str[BP] }
$26 / $8A / $0D / { Mov CL,ES:[DI] }
$FE / $C1 / { Inc CL }
$FE / $C9 / { L1: Dec CL }
$74 / $13 / { Jz L2 }
$47 / { Inc DI }
$26 / $80 / $3D / $61 / { Cmp ES:Byte Ptr [DI],'a' }
$72 / $F5 / { Jb L1 }
$26 / $80 / $3D / $7A / { Cmp ES:Byte Ptr [DI],'z' }
$77 / $EF / { Ja L1 }
$26 / $80 / $2D / $20 / { Sub ES:Byte Ptr [DI],20h }
$EB / $E9 { Jmp Short L1 }
) ; { L2: Ret }
END.
Usage:
This example disables the Control Break Interrupt 23h
CONST
Int23 : String [5] = 'xxxxx' ;
{ Value is not important
[0] - string length
[1] - CS saved value (2 bytes)
[3] - IP saved value (2 bytes)
[5] - IRET value,$CF (1 byte )
}
TYPE
Str05 = String [5]; { Declare type for var paramter }
Procedure Set_Int23 (var parm1 : Str05);
Begin
Inline
( { Must save BP entry value }
$55 / { Push BP }
$8B / $EC / { Mov BP,SP }
$1E / { Push DS }
$06 / { Push ES }
{ Get current Int 23h CS:IP }
$B4 / $35 / { Mov AH,35h }
$B0 / $23 / { Mov AL,23h }
$CD / $21 / { Int 21h }
{ Get string address off stack }
$C5 / $76 / $08 / { Lds SI,[BP + 8] }
{ Save old CS:IP in string CONST }
$8C / $44 / $01 / { Mov [SI+1],ES }
$89 / $5C / $03 / { Mov [SI+3],BX }
{ Set new Int 23h vector }
$B4 / $25 / { Mov AH,25h }
$B0 / $23 / { Mov AL,23h }
$8B / $D6 / { Mov DX,SI }
$83 / $C2 / $05 / { Add DX,5 }
{ Create IRET code in string }
$C6 / $44 / $05 / $CF / { Mov [SI+5],0CFh }
$CD / $21 / { Int 21h }
$07 / { Pop ES }
$1F / { Pop DS }
{ Must restore BP entry value }
$5D { Pop BP }
);
End;
BEGIN
Set_Int23 (Int23); { Redirect Ctrl Break to IRET }
END.
See Also:
External
Function
Intr
MsDos
Procedure
This page created by ng2html v1.05, the Norton guide to HTML conversion utility.
Written by Dave Pearson