Oppolzer - Informatik / Stanford Pascal Compiler
Home
Lebenslauf
Schwerpunkte
Kenntnisse
Seminare
Kunden
Projekte
Produkte
Blog
Stanford Pascal
Kontakt
The Stanford Pascal Compiler / Evolution Steps
Back to Compiler main page
Verifying new P-Code instructions with the PCINT debugging features
Compiler version: 12.2017
To allow assignments of shorter string variables to longer
string targets, I had to introduce a new P-Code instruction
MFI (memory fill). I'd like to show you here, how the PCINT
interpreter and its debugging features can be used to verify
that new P-Code instructions are implemented correctly.
First of all, here is the Pascal example used:
program TESTSVAR ( OUTPUT ) ;
type CHAR10 = array [ 1.. 10 ] of CHAR ;
CHAR30 = array [ 1.. 30 ] of CHAR ;
CHAR21 = array [ 20.. 40 ] of CHAR ;
var F10 : CHAR10 ;
F30 : CHAR30 ;
F21 : CHAR21 ;
begin (* HAUPTPROGRAMM *)
F10 := 'Oppolzer' ;
F30 := F10 ;
WRITELN ( F30 ) ;
F21 := 'Teststring Length 21' ;
F30 := F21 ;
WRITELN ( F30 ) ;
F21 := F30 ;
end (* HAUPTPROGRAMM *) .
|
You may notice that the assignments to F30 are ok,
but the assignment to F21 is wrong, because F21
is shorter than F30. This is what the compiler says, too:
c:\work\pascal\work>pp testsvar
PCINT (Build 1.0 Nov 11 2017 08:49:28)
**** STANFORD PASCAL COMPILER, OPPOLZER VERSION OF 12.2017 ****
21 F21 := F30 ;
!
+++ Error P129: TYPE CONFLICT OF OPERANDS
**** Compiler Summary ****
**** 1 Error.
**** 22 LINE(S) READ, 0 PROCEDURE(S) COMPILED,
**** 38 P_INSTRUCTIONS GENERATED,
0.05 SECONDS IN COMPILATION.
**** Last Error/Warning on Line 21
**** Error/Warning Codes for this Program:
**** P129: TYPE CONFLICT OF OPERANDS
*** EXIT Aufruf mit Parameter = 1 ***
|
Luckily, the compiler simply omits the erroneous statement 21,
so the resulting PRR file is usable, anyway. Here you
can see the beginning of the PRR file:
c:\work\pascal\work>type testsvar.prr
LOC 15
BGN TESTSVAR 10:31:22 11/12/2017
$PASMAIN ENT P,1,L3 $PASMAIN ,T,F,F,F,2,0,,
LDA 1,352
LCA M,10,'Oppolzer '
MOV 10
LOC 16
LDA 1,362
LDA 1,352
DBG 1
LDC C,' '
MFI -30
MOV 10
LOC 17
...
|
For debugging purposes, I generated the new DBG instruction
just before the instruction sequence which sets up the
MFI P-Code. DBG has no effect, if PCINT is started with
debug=n, but with debug=y, the interpreter enters the debug
dialog mode, when it encounters a DBG instruction. The operand
on DBG currently has no meaning.
I now start the program using debug=y. The program (the
PRR file) is translated into an internal memory representation
and then executed, but, because the debug switch is on,
execution stops at the very first P-Code instruction
(which is BGN).
c:\work\pascal\work>pcint prr=testsvar.prr inc=paslibx,pasutils,
pas=testsvar.pas out=testsvar.prrlis debug=y
PCINT (Build 1.0 Nov 11 2017 08:49:28)
ip=000001 sp=00000016 hp=02999984
00000000 00000000: 81818181 81818181 81818181 81818181 +................+
00000016 00000010: 81818181 81818181 81818181 81818181 +................+
000001: 007 0 1 BGN TESTSVAR 10:31:22 11/12/2017
g
|
The "g" command starts unlimited execution, but in this case
execution stops, when the interpreter encounters the DBG instruction
(in fact, after it processed the DBG instruction).
ip=000010 sp=00000024 hp=02999984
00000008 00000008: 81818181 81818181 81818181 6A010000 +............j...+
00000024 00000018: 60010000 81818181 81818181 81818181 +................+
00000040 00000028: 81818181 81818181 +........ +
000010: 041 C 0 32 LDC C,' '
asm
|
I switch to ASM mode using the "asm" command;
in PAS mode, the debugger only stops once for every
Pascal statement and not for every P-Code instruction.
*** Mode ASM set
ip=000010 sp=00000024 hp=02999984
00000008 00000008: 81818181 81818181 81818181 6A010000 +............j...+
00000024 00000018: 60010000 81818181 81818181 81818181 +................+
00000040 00000028: 81818181 81818181 +........ +
000010: 041 C 0 32 LDC C,' '
s
|
Now I step one instruction forward using the "s" command.
ip=000011 sp=00000028 hp=02999984
00000012 0000000c: 81818181 81818181 6A010000 60010000 +........j.......+
00000028 0000001c: 20000000 81818181 81818181 81818181 + ...............+
00000044 0000002c: 81818181 81818181 81818181 +............ +
000011: 047 0 -30 MFI -30
d x16a x180
|
You may notice that the stack pointer SP has increased to
28; and the stack now contains the blank (X'20') at the
topmost stack position. The address which will be the
target of the subsequent MFI instruction is x0000016a
(at the position sp - 8, little endian representation,
because we are on a Windows machine). So I'd like to
display the target area of the MFI instruction before
executing it. This is what the "d" command does (from
address ... to address, hex notation is possible).
00000362 0000016a: 81818181 81818181 81818181 81818181 +................+
00000378 0000017a: 81818181 8181 +...... +
ip=000011 sp=00000028 hp=02999984
00000012 0000000c: 81818181 81818181 6A010000 60010000 +........j.......+
00000028 0000001c: 20000000 81818181 81818181 81818181 + ...............+
00000044 0000002c: 81818181 81818181 81818181 +............ +
000011: 047 0 -30 MFI -30
s
|
The area (only 22 bytes are shown) is undefined; x'81'
is the initialization pattern used by the runtime.
So now I will execute the new implemented MFI instruction,
to see, how it works ... using the "s" command.
ip=000012 sp=00000024 hp=02999984
00000008 00000008: 81818181 81818181 81818181 6A010000 +............j...+
00000024 00000018: 60010000 20000000 81818181 81818181 +.... ...........+
00000040 00000028: 81818181 81818181 +........ +
000012: 049 0 10 MOV 10
d x16a x180
|
Obviously, it popped one item from the stack, which is correct.
Now let's see, if the area is filled correctly, by again
displaying it.
00000362 0000016a: 20202020 20202020 20202020 20202020 + +
00000378 0000017a: 20202020 2020 + +
ip=000012 sp=00000024 hp=02999984
00000008 00000008: 81818181 81818181 81818181 6A010000 +............j...+
00000024 00000018: 60010000 20000000 81818181 81818181 +.... ...........+
00000040 00000028: 81818181 81818181 +........ +
000012: 049 0 10 MOV 10
s
|
Looks good; now I execute the next instruction (MOV,
using a length of 10).
ip=000013 sp=00000016 hp=02999984
00000000 00000000: 81818181 81818181 81818181 81818181 +................+
00000016 00000010: 81818181 6A010000 60010000 20000000 +....j....... ...+
000013: 044 0 17 LOC 17
*** LOC 17: WRITELN ( F30 ) ;
g
|
The next instructions write the F30 buffer, so I will
see the result anyway. I continue by using the "g" command.
Oppolzer
ip=000030 sp=00000024 hp=02999984
00000008 00000008: 81818181 81818181 81818181 6A010000 +............j...+
00000024 00000018: 88010000 1E000000 1E000000 81818181 +................+
00000040 00000028: 81818181 81818181 +........ +
000030: 041 C 0 32 LDC C,' '
s
ip=000031 sp=00000028 hp=02999984
00000012 0000000c: 81818181 81818181 6A010000 88010000 +........j.......+
00000028 0000001c: 20000000 1E000000 81818181 81818181 + ...............+
00000044 0000002c: 81818181 81818181 81818181 +............ +
000031: 047 0 -30 MFI -30
s
ip=000032 sp=00000024 hp=02999984
00000008 00000008: 81818181 81818181 81818181 6A010000 +............j...+
00000024 00000018: 88010000 20000000 1E000000 81818181 +.... ...........+
00000040 00000028: 81818181 81818181 +........ +
000032: 049 0 21 MOV 21
s
ip=000033 sp=00000016 hp=02999984
00000000 00000000: 81818181 81818181 81818181 81818181 +................+
00000016 00000010: 81818181 6A010000 88010000 20000000 +....j....... ...+
000033: 044 0 20 LOC 20
*** LOC 20: WRITELN ( F30 ) ;
g
|
The content of F30 is shown correctly, as expected.
Because there is another MFI in the code, execution
stops again. I walk along the code using "s" commands
(watch SP changing) and then use "g" to execute the
rest of the program.
Teststring Length 21
c:\work\pascal\work>
|
This debug session proved IMO, that the new P-Code
instruction works as desired. I finish by calling the
program using debug=n; there should be no interruption.
c:\work\pascal\work>prun testsvar
c:\work\pascal\work>pcint prr=testsvar.prr inc=paslibx,pasutils,
pas=testsvar.pas out=testsvar.prrlis
PCINT (Build 1.0 Nov 11 2017 08:49:28)
Oppolzer
Teststring Length 21
c:\work\pascal\work>
|
If you want to use the debug features of PCINT yourself,
start it using debug=y and enter a question mark on the
first prompt; you will get a short online help telling the
available commands (at the moment in German, only ... sorry).
Warning: the actual version of PCINT may not work this way;
you may have to wait for the 12.2017 version.
Back to Compiler main page