home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Vectronix 2
/
VECTRONIX2.iso
/
FILES_01
/
HISPEED2.LZH
/
NEWDOC
/
IA.DOC
< prev
Wrap
Text File
|
1991-04-01
|
8KB
|
258 lines
New for version 1.1, ASM, ASSEMBLER
New Chapter
The Inline Assembler
HighSpeed Pascal enables you to type assembly source directly into the
Pascal source. The full 68000 instruction set is supported.
The assembler does not know of the size of a used Pascal variable.
It is up to you to specify the right size on each assembly instruction
if not using the default word size. If you code
ASM move MyLongInt,d0 END;
you end up with only the hi part from the longint MyLongInt.
The assembler makes is much faster to write small code pieces without
having to use the Inline or external system. Of cause, you can still
use inline and external.
The only directives implemented is DC to define constant blocks in the
code. All other needed features must be coded in Pascal. The assembler
can read Pascal constants and variables.
These are the registers known by the assembler:
D0, D1, D2, D3, D4, D5, D6, D7,
A0, A1, A2, A3, A4, A5, A6, A7,
SP, USP, PC, CCR, SR
Special variables only known to the assembler:
@RESULT
These are the 68000 instructions known by the assembler:
ABCD, ADD, ADDA, ADDI, ADDQ, ADDX, AND, ANDI, ASL, ASR
BCC, BCHG, BCLR, BCS, BEQ, BGE, BGT, BHI, BHS, BLE, BLO, BLS, BLT,
BMI, BNE, BNZ, BPL, BRA, BSET, BSR, BTST, BVC, BVS, BZE
CHK, CLR, CMP, CMPA, CMPI, CMPM
DBCC, DBCS, DBEQ, DBF, DBGE, DBGT, DBHI, DBHS, DBLE, DBLO, DBLS, DBLT,
DBMI, DBNE, DBNZ, DBPL, DBRA, DBT, DBVC, DBVS, DBZE, DIVS, DIVU
EOR, EORI, EXG, EXT, ILLEGAL, JMP, JSR, LEA, LINK, LSL, LSR
MOVE, MOVEA, MOVEM, MOVEP, MOVEQ, MULS, MULU
NBCD, NEG, NEGX, NOP, NOT, OR, ORI, PEA
RESET, ROL, ROR, ROXL, ROXR, RTE, RTR, RTS
SBCD, SCC, SCS, SEQ, SF, SGE, SGT, SHI, SHS, SLE, SLO, SLS, SLT, SMI,
SNE, SNZ, SPL, ST, STOP, SUB, SUBA, SUBI, SUBQ, SUBX, SVC, SVS, SWAP, SZE
TAS, TRAP, TRAPV, TST, UNLK
You will have to find the description of these instructions somewhere else
outside this manual.
The assembler is accessed through an ASM statement. The syntax of an ASM
statement is:
ASM [Label:] AsmStmt < Separator AsmStmt > END;
where Label is an optional label and AsmStmt is one assembler statement.
The Separator is either a semicolon or a new-line. Notice that this is
different from the rest of the HighSpeed Pascal compiler where a new-line
only counts as a space. More than one AsmStmt can be placed on one line
separated by semicolons or they can be placed one on each line just like
that.
An example:
Function Add3(X, Y, Z: Integer): Integer;
begin
ASM
move.w X,d0
add.w Y,d0
add.w Z,d0
move.w d0,@result
END;
end;
<2>Labels
Labels declared in a Pascal label declaration can be used and/or defined
in an ASM statement. But because assembly coding usually makes a lot of
labels you can also make local labels in the ASM statement.
Local labels do not have to be declared in a label declaration but gets
known first time used. They are declared by writing an at-sign (@) as the
first character.
<2>ASSEMBLER procedure and functions
If the the ASM END statement is the only statement in a procedure
(or function) the procedure can be declared as an ASSEMBLER procedure.
This removes the need for the BEGIN END block. The The Add3 function
can now be written as:
Function Add3(X, Y, Z: Integer): Integer; ASSEMBLER;
ASM
move.w X,d0
add.w Y,d0
add.w Z,d0
move.w d0,@result
END;
It looks more clean. But beside the obvious savings, the compiler also
speeds up your code because of some optimization: Value parameters are
never copied to local area. This saves code and time. But you must take
care yourself because you are not allowed to change these value variables.
In the following example the variable P is a value parameter. As can be
seen in the appendix 'Inside HighSpeed' section 'Value Parameters' only
the address of a string is passed to the procedure. Because of the
ASSEMBLER directive you only get the address of the original string.
Without the ASSEMBLER directive you would have written LEA P,A0 instead.
Type C_Str=PACKED array[0..255] of char;
Procedure PasToCStr(P: String; var C: C_Str ); ASSEMBLER;
ASM MOVE.L P,A0 {Address of the Pascal string}
MOVE.L C,A1 {Address of the C string}
MOVEQ #0,D0
MOVE.B (A0)+,D0 {String length}
BRA @L2
@L1: MOVE.B (A0)+,(A1)+
@L2: DBRA D0,@L1
CLR.B (A1) {Terminate the C string}
END;
<2>Assembler directives
The only directive known is DC, Define Constant. It takes the three
sizes .B, .W and .L.
DC.B blocks does always make an even number of bytes.
Examples:
ASM
DC.B 11,'Hello World' {Pascal string}
DC.B 'Hello World',0 {C string}
DC.B 1,2,3+4+5
DC.W 7,9,13
DC.L 1
END;
<2>Expressions
It is important to notice that expressions does not always act the same
way in assembly as in Pascal.
Assume:
Const
X=4;
Y=7;
Var
M,N,O: Integer;
A: Array[0..99] of Integer;
We want to code the following in assembly:
M:=X+Y;
M:=N+X;
M:=A[3];
The right way:
ASM
MOVE.W #X+Y,M {M:=X+Y}
MOVE.W N,D0 {M:=N+X}
ADD.W #Y,D0
MOVE.W D0,M
MOVE.W A+2*3,M {M:=A[3]. 2 because Integer}
END;
The wrong way:
ASM
MOVE.W X+Y,M {M:=X+Y}
MOVE.W N+X,M {M:=N+X}
MOVE.W A,D0 {M:=A[3]}
ADD.W #3*2,D0
MOVE.W D0,M
END;
Registers
These are the CPU registers known by the assembler:
Data registers: D0, D1, D2, D3, D4, D5, D6, D7,
Data registers: A0, A1, A2, A3, A4, A5, A6, A7, SP
Special registers: USP, PC, CCR, SR
The @result variable represents the position on the stack of the returned
result. Remember that @result can either be the position of the result or
a pointer to the result. Look in the appendix 'Inside HighSpeed' section
'Function Results' for more information.
Addressing modes
The following is the 68000 CPU's addressing modes:
Dn Data register
An Address register direct
(An) Address register indirect
(An)+ Address register indirect w/postincrement
-(An) Address register indirect w/predecrement
d(An) Address register indirect w/disp
d(An,Rn) Address register indirect w/disp and index
XXXX Absolute short
XXXXXXXX Absolute long
d(PC) Program counter indirect w/disp
d(PC,Rn) Program counter indirect w/disp and index
#XXXX Immediate data
The Rn index field can be Dn, An, Dn.S, An.S where S is W or L for word
or long.
The displacement on the two formats with index must be written. If zero
then write a zero.
Operators
The following is the defined operators for use in expressions:
Highest precedence:
+ Unary plus. Does nothing
- Unary minus. Returns the negated value
! Unary negation. Return the bitwise not value
Second highest precedence:
* Multiplication
/ Integer division
% Integer remainder
& Bitwise and
<< Logical shift left
>> Logical shift right
Lowest precedence:
+ Addition
- Subtraction
| Bitwise or
^ Bitwise xor
Limitations
Jumps with BRA, BSR etc can only be done using word offsets. BRA.B or
BRA.S is not allowed.
The only way of getting an address in the code is by using LEA or PEA
(or by jumping to it/calling it).
ASM
LEA @MyData,a0 {Ok}
PEA @MyData {Ok}
MOVE.W @MyData,d0 {Wrong!}
@MyData: DC.W 1,2,3,4,5
END;
The addressing mode (An,Rn.S) and (PC,Rn.S) must be prefixed by an
expression. it is not allowed to write PEA (A0,D0). Instead write
PEA 0(A0,D0).