igor1985 Thanks for the response. But the stack as you are explaining is not the problem.
1 2 3 4
|
push word ptr a1 // pushes a word 2 bytes data
push offset a2 // pushes an address 4 bytes
call something
add esp,6 // adjust stack for 6 bytes pushed
| |
The code above shows a valid way of removing passed arguments. At least on older versions of windows and using CodeWarrior 8 ide. However CodeWarrior is an old program and I have to keep closing it and reloading and eventually reloading windows to get it to compile and debug. I get a windows pop up system error caused by CodeWarior. Usually when starting a debug. Sometimes when starting a build. With VC2010 when debugging I get a run time error on the stack adjustments.
This is part meta compiler compiler I am implementing. It is basically all assembly code. Not standard c or c++. The functions are naked assembly function like the above. ebp is used to mark a parser backup point. Not the normal uses as a base pointer.
Syntax rules are compiled into machine code not a table. I am hand compiling the compiler into IA86 code. I have been programming sense 1965. Mostly in assembly. I assure you that I know what I am doing with the stack. It is not the standard C usage. This has to do with VC2010 debugger.
The following library routines illustrate stack manipulation. Hopefully the comments are enough explanation:
The success or failure of a match is returned in the zero flag.
call <rule>
je <success>
or
jne <failure>
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
|
/************** Set up functions for cc matching function **************\
* *
* cc matching function are called by token making and grammer rules to *
* match strings and characters in the input stream. *
* *
* !! This s assembly code in a C++ wraper !!!! *
* *
* __savePntrs is called on entry by string match function to save the *
* input stream state required to Back Track a failed match. The back *
* tracking does not have to handle reentricy or stacked states. Objects*
* are not put on the parse stack or node stack by them. Back Tracking *
* is only done when they fail so only the input stream state is saved *
* staticly. *
* *
* On success a match function simply returns success. On failure it *
* must restore the input stream state. To restore the input stream *
* use the folowing: *
* *
* jmp __rstrPntrs *
* *
* __rstrPntrs is alwayse jumped to on failure by a matching *
* function and only restores the input stream state *
* *
* The token skipclass skiping is also affected by matching functions *
* When called from a token rule a match will set the partial match *
* flag that prevents further skipclass skipping. The flag may only be *
* set when a token rule is active. *
* *
\***********************************************************************/
__declspec(naked) void __savePntrs(){_asm{ // crazy stack minipulation!!
/***********************************************************************\
* __savePntrs saves input stream state for string match function call: *
* *
* push offset <string address> // string to match *
* call _match_function_ // _CmpStr _KeepStr _NotStr *
* <return eq: success ne: failure: i.e. je someware // on success> *
* *
* on entry a match function calls __savePntrs *
* *
*__declspec(naked) void _match_function_() {_asm{ *
* call __savePntrs *
* <return from __savePntrs> *
* *
* stack on entry to __savePntrs: *
* [esp+8] <string ptr> *
* [esp+4] <return from _matching function_> *
* [esp+0] <return from __savePntrs> to _matching function_ *
* *
* rearange stack: Stack on entry as above *
* *
* preserving the calling rule's ecx *
\***********************************************************************/
xchg ecx,[esp+4] // swap ecx for _matching function_'s return
xchg ecx,[esp+8] // swap return for char* str
/********************* stack is not arranged so: ***********************\
* [esp+8] <return from _matching function_> *
* [esp+4] callers saved ecx *
* [esp+0] <return from __savePntrs> to _matching function_ *
* ecx <string address> pointer *
* *
* Stack now as above with ecx *string parameter from [esp+8] on entry *
* *
\***********************************************************************/
mov strng_parm,ecx // save string parameter pointer
mov ecx,InPutFCB // point ecx at FCB
<file control block saved, code not shown >
...
mov al,TokenFlg // save corrent flags state
mov token_stats,al // so can be restored on fail
// Got TokenFlg skipclass state. Matching can not skip skipclass once any
// characters have been matchd. That state is pased back to the matching
// function in the zero status flag by the following test instruction.
mov eax,FCB_dataptr(ecx) //
movzx eax,byte ptr [eax] // get input stream character
mov ecx,strng_parm // point ecx at string parameter
ret
/***********************************************************************\
* *
* Stack on return to match function: *
* *
* [esp+4] origional <return from _matching function_> *
* [esp+0] callers saved ecx <must be poped by functon> *
* ecx points at string to match <string address> *
* NOTE. __rstrPntrs will restore callers ecx. Do not pop ecx *
* *
* ecx only need be poped on success before a return. *
* pop ecx // needs restoring *
* ret // before a successful return *
* *
* NO POP ECX before: *
* jmp __rstrPntrs // ecx will be restored by __rstrPntrs *
* *
* Input stream state saved. *
\***********************************************************************/
}}
// **************************************************************
// ********* NEVER EVER CALL THIS FUNCTION EVER NEVER *********
//
__declspec(naked) void __rstrPntrs(){_asm{ // match string reset input stream.
// !*!*!*!*!*!*!*!*! COMMON FAIL EXIT CODE !*!*!*!*!*!*!*!*!
// !*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
// !*!*!*! __rstrPntrs is always jumped to with saved !*!*!*!
// !*!*!*! ecx left on the stack to restore on exit. !*!*!*!
// !*!*!*! THIS FUNCTION IS ALWAYS JMPed to !*!*!*!
// !*!*!*! NEVER EVER !! CALLED !! NEVER EVER !*!*!*!
// !*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
// !*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
<file control block restored, code not shown data pointer excepted>
mov eax,markdataptr // get daved data pointer
mov FCB_dataptr(ecx),eax // restore to stream pointer
movzx eax,byte ptr [ecx] // eax:curent stream character
pop ecx // ecx of match functions restored
ret // return failure. ne condition
}}
| |
Grammar rules are extended bnf parsing tree/list building rules:
1 2
|
expr = term $(('+':ADD|'-':SUB) tern!2);
term = factor $(('*':MPY|'/':DIV) factor!2);
| |
the expresion
a*b+(c/5-d);
trnasforms to
ADD[MPY[a,b],SUB[DIV[c,5],d]]
The tree processing language:
1 2 3 4 5 6 7
|
arith(ADD[arith(x),arith(y)])=> <add x,y;>;
arith(SUB[arith(x),arith(y)])=> <sub x,y;>;
arith(MPY[arith(x),arith(y)])=> <mpy x,y;>;
arith(DIV[arith(x),arith(y)])=> <div x,y;>;
arith(x)=> %r1=asignreg()=> %r1=assignreg();
<loadreg %r1,x>;
| |
Sorry if I made this sound like a coding problem.