-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathanalyseras.frt
152 lines (123 loc) · 5.2 KB
/
analyseras.frt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
( Copyright{2000}: Albert van der Horst, HCC FIG Holland by GNU Public License)
( $Id: analyseras.frt,v 5.5 2019/11/08 14:11:29 albert Exp $)
\ ------------------ assembler stuff here -----------------------------------
\ WARNING: HEX THROUGHOUT THIS WHOLE FILE !
WANT IN-BAG?
HEX
ASSEMBLER BITS-64
CREATE POPS HERE 0 ,
' POP, , ' POPF, ,
' POP|DS, , ' POP|ES, , ' POP|FS, ,
' POP|GS, , ' POP|SS, , ' POP|X, ,
HERE SWAP !
CREATE PUSHES HERE 0 ,
' PUSH, , ' PUSHF, , ' PUSHI|B, ,
' PUSHI|X, , ' PUSH|CS, ,
' PUSH|DS, , ' PUSH|ES, , ' PUSH|FS, ,
' PUSH|GS, , ' PUSH|SS, ,
' PUSH|X, ,
HERE SWAP !
\ Instruction that have an input side effect.
\ Two operand instructions are handled directly, via ``T|'' ``F|''
CREATE FETCHES HERE 0 ,
' MOV|TA, , ' LODS, ,
' SCAS, , ' CMPS, , ' MOVS, ,
' OUTS, , ' INS, , ' OUT|D, ,
' IN|D, , ' OUT|P, , ' IN|P, ,
' SCAS, , ' INT, ,
HERE SWAP !
\ Instruction that have an output side effect.
\ Two operand instructions are handled directly, via ``T|'' ``F|''
CREATE STORES HERE 0 ,
' MOV|FA, , ' STOS, ,
' MOVS, ,
' OUTS, , ' INS, , ' OUT|D, ,
' IN|D, , ' OUT|P, , ' IN|P, ,
' INT, ,
HERE SWAP !
\ Instruction that use EDI. Normally this is not done.
\ But some (string) operations require it.
\ Probably double precision div with result in EDI belongs here.
\ CREATE EDIERS HERE 0 ,
\ ' STOS, ,
\ ' SCAS, , ' CMPS, , ' MOVS, ,
\ HERE SWAP !
\ Bookkeeping for pops and pushes.
VARIABLE #POPS VARIABLE #PUSHES
: !PP 0 #POPS ! 0 #PUSHES ! ;
\ After a call to ``(DISASSEMBLE)'' return the OPCODE.
: OPCODE DISS CELL+ @ ;
\ Add the bookkeeping of pops and pushes for the latest instruction
\ dissassembled.
: COUNT-PP
OPCODE POPS IN-BAG? #PUSHES @ IF #PUSHES +! ELSE NEGATE #POPS +! THEN
OPCODE PUSHES IN-BAG? NEGATE #PUSHES +! ;
\ Bookkeeping for input and output side effects.
VARIABLE PROTO-FMASK
\ Initialise to "no side effects". Innocent until proven guilty.
: !FMASK FMASK-NS PROTO-FMASK ! ;
\ A forth flag has all bit set. Hence the idiom ``FLAG MASK AND''
\ instead of FLAG IF MASK ELSE 0 THEN''. Also note that in Stallman
\ convention a capitalised verb means a (forth) flag.
\ Add to FLAGS if instruction IS storing, the no output side effects flag.
\ Return the new FLAGS. (So those are the flags to become invalid.)
: IS-STORING FMASK-N! AND OR ;
\ Add to FLAGS if instruction IS looping, i.e. it uses register IDE.
\ Return the new FLAGS. (So those are the flags to become invalid.)
\ Comment in whenever -FDI gets used.
\ : IS-LOOPING FMASK-FDI AND OR ;
\ Add to FLAGS if instruction IS fetching, the no input side effects flag.
\ Return the new FLAGS. (So those are the flags to become invalid.)
: IS-FETCHING FMASK-N@ AND OR ;
\ Look whether we have the current disassembled instruction forces us to
\ revise the flag mask.
: REVISE-FMASK
0
OPCODE STORES IN-BAG? IS-STORING
OPCODE FETCHES IN-BAG? IS-FETCHING
\ OPCODE EDIERS IN-BAG? IS-LOOPING \ See IS-LOOPING
'R| DISS IN-BAG? 0= IF
'T| DISS IN-BAG? IS-FETCHING
'F| DISS IN-BAG? IS-STORING
\ Memory (non-move) operations always fetch!
'F| DISS IN-BAG? 'MOV, OPCODE <> AND IS-FETCHING
THEN
\ Overrule : operations on the return stack don't count.
'[BP] DISS IN-BAG? IF DROP 0 THEN
PROTO-FMASK AND!U
;
\ Accumulate information for an assembler definition from address ONE to
\ address TWO.
\ Count pushes and pops among the instructions.
\ Find out about `no input side effect' and `no output side effect'.
: ACCUMULATE-AS-INFO
SWAP
!PP !FMASK
BEGIN 2DUP > WHILE
(DISASSEMBLE) ^M EMIT COUNT-PP REVISE-FMASK
REPEAT
2DROP
;
\ Define a ``NEXT'' sequence. It must have the exact code that is in
\ the kernel.
: NEXT Q: LODS, X'| JMPO, ZO| [AX] ;
PREVIOUS
\ The sequence of bytes that forms next, as a string.
\ (This means you can $@ it.)
CREATE NEXT-IDENTIFICATION 0 , NEXT
HERE NEXT-IDENTIFICATION CELL+ - NEXT-IDENTIFICATION !
\ \D ." Expect NEXT-IDENTIFICATION to contain NEXT :" CR
\ \D : DUMP-STRING
\ \D OVER H. SPACE DUP H. DUMP ;
\ \D NEXT-IDENTIFICATION $@ DUMP-STRING
\ For some code at ADDRESS, find the start ADDRESS of its ``NEXT''.
: >NA BEGIN DUP NEXT-IDENTIFICATION $@ CORA WHILE 1+ REPEAT ;
\ Get the pops and pushes from DEA which must be a code definition.
\ Get also its side effect mask.
: ANALYSE-CODE >CFA @ DUP >NA ACCUMULATE-AS-INFO ;
\ For DEA fill in the stack effect byte and the side effect mask.
\ It must be a code definition.
: FILL-FLAG-CODE >R R@ ANALYSE-CODE
PROTO-FMASK @ #POPS @ #PUSHES @ R> !FLAGS ;
\ ------------------------------------------------
DECIMAL