Turbo51 Assembler Procedures
Pascal Compiler for 8051 Microcontrollers
Here you can see some examples of procedures written entirely in 8051 assembly language. At the end of each procedure Turbo51 adds only RET instruction (or RETI in interrupt procedure). Turbo51 automatically removes RET instruction at the end of procedure if it finds out that it will not be reached. If for some reason RET instruction is not removed and you don't want it you can use the $NoReturn compiler directive inside assembler procedure to prevent generating RET instruction. You can easily pass parameters by value (Turbo51 automatically creates static variables for value storage), by reference (Turbo51 automatically creates static variables for pointer storage) or you can pass values in registers. Procedure's parameters can be accessed as local variables with Procedure.Parameter. See also assembler statement.
Program AssemblerProcedures;
{ Useless program just to demostrate assembler procedures }
Const DemoText = 'Turbo51 assembler procedures demo';
ZeroTerminated = 'Zero terminated';
DemoString: String [Length (DemoText)] = DemoText;
String0: Array [0 .. Length (ZeroTerminated)] of Char = ZeroTerminated;
Var Number1, Number2, Result: Word;
Procedure Add; Assembler;
Asm
MOV A, Number1
ADD A, Number2
MOV Result, A
MOV A, Number1 + 1
ADDC A, Number2 + 1
MOV Result + 1, A
end;
Procedure Multiply; Assembler;
Asm
MOV R2, Number1
MOV R3, Number1 + 1
MOV R6, Number2
MOV R7, Number2 + 1
MOV A, R2
MOV B, R6
MUL AB
XCH A, R2
XCH A, R7
XCH A, B
XCH A, R7
MUL AB
ADD A, R7
XCH A, R3
MOV B, R6
MUL AB
ADD A, R3
MOV R3, A
MOV Result, R2
MOV Result + 1, R3
end;
Procedure CalculateXorValue (Num1, Num2: Word); Assembler;
Asm
MOV A, Num1
XRL A, Num2
MOV R2, A
MOV A, Num1 + 1
XRL A, Num2 + 1
MOV R3, A
end;
Procedure SwapWords (Var Num1, Num2: Word); Assembler;
Asm
MOV R0, Num1
MOV R1, Num2
MOV B, @R0
MOV A, @R1
MOV @R0, A
MOV @R1, B
INC R0
INC R1
MOV B, @R0
MOV A, @R1
MOV @R0, A
MOV @R1, B
end;
Procedure WriteString; Assembler;
Asm
// Code to write string in code with address in DPTR
end;
Procedure WriteZeroTerminatedString; Assembler;
Asm
// Code to write zero terminated string in code with address in DPTR
end;
Procedure WriteResult; Assembler;
Asm
// Code to write number in Result variable
end;
begin
Asm
MOV DPTR, #DemoString
LCALL WriteString
MOV DPTR, #String0
LCALL WriteZeroTerminatedString
MOV Number1, #LOW (200)
MOV Number1 + 1, #HIGH (200)
MOV Number2, #LOW (40)
MOV Number2 + 1, #HIGH (40)
LCALL Add
LCALL WriteResult
MOV Number1, #LOW (2000)
MOV Number1 + 1, #HIGH (2000)
MOV Number2, #LOW (45)
MOV Number2 + 1, #HIGH (45)
LCALL Multiply
LCALL WriteResult
MOV CalculateXorValue.Num1, #LOW ($1234)
MOV CalculateXorValue.Num1 + 1, #HIGH ($1234)
MOV CalculateXorValue.Num2, #LOW (10000)
MOV CalculateXorValue.Num2 + 1, #HIGH (10000)
LCALL CalculateXorValue
MOV Result, R2
MOV Result + 1, R3
LCALL WriteResult
MOV Number1, #LOW (2000)
MOV Number1 + 1, #HIGH (2000)
MOV Number2, #LOW (45)
MOV Number2 + 1, #HIGH (45)
MOV SwapWords.Num1, #Number1
MOV SwapWords.Num2, #Number2
LCALL SwapWords
LCALL WriteResult
end;
end.
Compiled program looks like this:
; Turbo51 version 0.1.3.10, Copyright 2000 - 2011 Igor Funa
$REGISTERBANK (0)
_CODE SEGMENT CODE
_CONST SEGMENT CODE
_DATA SEGMENT DATA
EXTRN IDATA (StackStart)
; Program AssemblerProcedures;
;
; { Useless program just to demostrate assembler procedures }
;
; Const DemoText = 'Turbo51 assembler procedures demo';
RSEG _CONST
; ZeroTerminated = 'Zero terminated';
;
; DemoString: String [Length (DemoText)] = DemoText;
DemoString: DB 33, 'Turbo51 assembler procedures demo'
; String0: Array [0 .. Length (ZeroTerminated)] of Char = ZeroTerminated;
String0: DB 'Zero terminated', 0
;
;
; Var Number1, Number2, Result: Word;
RSEG _DATA
Number1: DS 2
Number2: DS 2
Result: DS 2
;
; Procedure Add; Assembler;
RSEG _CODE
USING 0
Add:
; Asm
; MOV A, Number1
MOV A, Number1
; ADD A, Number2
ADD A, Number2
; MOV Result, A
MOV Result, A
; MOV A, Number1 + 1
MOV A, Number1+1
; ADDC A, Number2 + 1
ADDC A, Number2+1
; MOV Result + 1, A
MOV Result+1, A
; end;
RET
;
; Procedure Multiply; Assembler;
Multiply:
; Asm
; MOV R2, Number1
MOV R2, Number1
; MOV R3, Number1 + 1
MOV R3, Number1+1
; MOV R6, Number2
MOV R6, Number2
; MOV R7, Number2 + 1
MOV R7, Number2+1
;
; MOV A, R2
MOV A, R2
; MOV B, R6
MOV B, R6
; MUL AB
MUL AB
; XCH A, R2
XCH A, R2
; XCH A, R7
XCH A, R7
; XCH A, B
XCH A, B
; XCH A, R7
XCH A, R7
; MUL AB
MUL AB
; ADD A, R7
ADD A, R7
; XCH A, R3
XCH A, R3
; MOV B, R6
MOV B, R6
; MUL AB
MUL AB
; ADD A, R3
ADD A, R3
; MOV R3, A
MOV R3, A
;
; MOV Result, R2
MOV Result, R2
; MOV Result + 1, R3
MOV Result+1, R3
; end;
RET
;
;
; Procedure CalculateXorValue (Num1, Num2: Word); Assembler;
RSEG _DATA
Num1: DS 2
Num2: DS 2
RSEG _CODE
CalculateXorValue:
; Asm
; MOV A, Num1
MOV A, Num1
; XRL A, Num2
XRL A, Num2
; MOV R2, A
MOV R2, A
; MOV A, Num1 + 1
MOV A, Num1+1
; XRL A, Num2 + 1
XRL A, Num2+1
; MOV R3, A
MOV R3, A
; end;
RET
;
; Procedure SwapWords (Var Num1, Num2: Word); Assembler;
RSEG _DATA
Num1: DS 1
Num2: DS 1
RSEG _CODE
SwapWords:
; Asm
; MOV R0, Num1
MOV R0, Num1
; MOV R1, Num2
MOV R1, Num2
;
; MOV B, @R0
MOV B, @R0
; MOV A, @R1
MOV A, @R1
; MOV @R0, A
MOV @R0, A
; MOV @R1, B
MOV @R1, B
;
; INC R0
INC R0
; INC R1
INC R1
;
; MOV B, @R0
MOV B, @R0
; MOV A, @R1
MOV A, @R1
; MOV @R0, A
MOV @R0, A
; MOV @R1, B
MOV @R1, B
; end;
RET
;
; Procedure WriteString; Assembler;
WriteString:
; Asm
; // Code to write string in code with address in DPTR
; end;
RET
;
; Procedure WriteZeroTerminatedString; Assembler;
WriteZeroTerminatedString:
; Asm
; // Code to write zero terminated string in code with address in DPTR
; end;
RET
;
; Procedure WriteResult; Assembler;
WriteResult:
; Asm
; // Code to write number in Result variable
; end;
RET
CSEG AT $0000
AssemblerProcedures:
;
; begin
MOV SP, #StackStart-1
; Asm
; MOV DPTR, #DemoString
MOV DPTR, #DemoString
; LCALL WriteString
LCALL WriteString
;
; MOV DPTR, #String0
MOV DPTR, #String0
; LCALL WriteZeroTerminatedString
LCALL WriteZeroTerminatedString
;
; MOV Number1, #LOW (200)
MOV Number1, #$C8
; MOV Number1 + 1, #HIGH (200)
MOV Number1+1, #0
; MOV Number2, #LOW (40)
MOV Number2, #$28
; MOV Number2 + 1, #HIGH (40)
MOV Number2+1, #0
; LCALL Add
LCALL Add
; LCALL WriteResult
LCALL WriteResult
;
; MOV Number1, #LOW (2000)
MOV Number1, #$D0
; MOV Number1 + 1, #HIGH (2000)
MOV Number1+1, #7
; MOV Number2, #LOW (45)
MOV Number2, #$2D
; MOV Number2 + 1, #HIGH (45)
MOV Number2+1, #0
; LCALL Multiply
LCALL Multiply
; LCALL WriteResult
LCALL WriteResult
;
; MOV CalculateXorValue.Num1, #LOW ($1234)
MOV CalculateXorValue.Num1, #$34
; MOV CalculateXorValue.Num1 + 1, #HIGH ($1234)
MOV CalculateXorValue.Num1+1, #$12
; MOV CalculateXorValue.Num2, #LOW (10000)
MOV CalculateXorValue.Num2, #$10
; MOV CalculateXorValue.Num2 + 1, #HIGH (10000)
MOV CalculateXorValue.Num2+1, #$27
; LCALL CalculateXorValue
LCALL CalculateXorValue
; MOV Result, R2
MOV Result, R2
; MOV Result + 1, R3
MOV Result+1, R3
; LCALL WriteResult
LCALL WriteResult
;
; MOV Number1, #LOW (2000)
MOV Number1, #$D0
; MOV Number1 + 1, #HIGH (2000)
MOV Number1+1, #7
; MOV Number2, #LOW (45)
MOV Number2, #$2D
; MOV Number2 + 1, #HIGH (45)
MOV Number2+1, #0
; MOV SwapWords.Num1, #Number1
MOV SwapWords.Num1, #Number1
; MOV SwapWords.Num2, #Number2
MOV SwapWords.Num2, #Number2
; LCALL SwapWords
LCALL SwapWords
; LCALL WriteResult
LCALL WriteResult
; end;
; end.
L_0061:
SJMP L_0061
RSEG _CONST
END
