1C: Assembleur - écrire un bytecode propre pour la machine empilée 1C: Enterprise


Les machines à pile sont utilisées dans une grande variété de langages de programmation modernes. Ils sont faciles à comprendre et en même temps assez efficaces. Vous voulez en essayer un en action?


Vous avez probablement tous entendu que les surnoms 1C se plaignent de leur système, étant donné que le langage 1C n'est pas assez bas, ennuyeux, etc. Tous regardent avec envie vers les "vrais" langages de programmation. Alors, messieurs, ils ont tort. Dans le système 1C, il existe des endroits où vous pouvez étirer le cerveau du programmeur et profiter de la technologie de bas niveau. Je vous suggère de plonger dans les entrailles de la machine virtuelle 1C et de comprendre comment cela fonctionne. Il a son propre «assembleur» et nous allons aujourd'hui y écrire du code de travail pour 1C. Venez sous la coupe, ce sera amusant!


Machines virtuelles empilées


Les langages de programmation dynamiques capturent de plus en plus le monde. Des langues natives "honnêtes" dans les rangs, peut-être, seulement C restait (avec des avantages et sans). C'est si nous prenons le courant dominant industriel. Tous les langages populaires, d'une manière ou d'une autre, ont une couche sous la forme d'un "environnement d'exécution" ou d'une "machine virtuelle", qui assure l'exécution de code sur une architecture particulière de fer. Et la grande majorité de ces "machines virtuelles" sont empilées, c'est-à-dire mettre en œuvre des opérations de traitement utilisant une telle structure connue dans le monde informatique sous le nom de «pile».


Remarque pour ceux qui ont oublié


(Stack) "". (, ) - , . . .. . "LIFO" — last in/first out. ( ). — .


Java, Python, C# 1 — . , node.js — , , . 95% , . JIT , , ? :)


, , . , — , -, . , . , — , . Java — . , . , , Java JVM — . ( ) Dalvik. , , . — , . , , , ( ) , , .


1 . — 1, — , 1Script. , .



. 2014 , .


, = 1 + 1; ?


PushConst 1
PushConst 1
Add
LoadVar A

- 1 (2 ), Add.


Add (2 ) . . LoadVar , ( — ).


. , = 1+1+2 :


PushConst 1 ;    
PushConst 1 ;    
Add ;  2    (1   1), ,    
PushConst 2 ;    
Add ;  2    (2   2), ,    
LoadVar A ;    ,    (4)     .

, , , : - - .


, , "-". "" .


- 1


, 1 - , , , . , , - - — . , 1 - . , , epf . v8unpack.



1. , .


epf. , chocolatey


choco install v8unpack --version 3.0.41 --source https://www.myget.org/F/onescript/api/v2

, chocolatey (, , ?) https://github.com/e8tools/v8unpack/releases/download/v.3.0.40/v8unpack.exe exe PATH, .


, 1, , .


v8unpack -P .epf content

content, 1 ( — : https://infostart.ru/public/250142/)


, "<--GUID>.0", "info" "text". "text" , , . content . "" " ". , .



, ? , content


v8unpack -P .epf content

GUID.0 , image, text — - . , , - , ? 1 - image. :



— 1. , . , ? , ! ? , !


?


, -, , , . .


-, , - 1 , . 1-, , . " 1" , . , , , 1. . , ?


. , , , .. . . , 1 . , , ( ) " ", " 1" — , .


, . , . - -, 1 . , .


: , ( , ), , , .


, ?


- 1, . - .


, v8unpack "" "image", .



, , , 1.


""


(). — . (OpCode), . , . . , , . ( ). , , — : .


? 1 128, , . .


""


. - , — , — . " ", . .. - , , / . , / . , .


. , , "". " = 2" 1 . . " - ".


""


1 ( ) . - ( ). , . . "", ( ) , .



-?


. — , — , . 2 1.


2. 0 .


2 2 :


LdConst 0
LdConst 0
Add 0

! : , - , Ld "Load". , .


LdConst , ( , 0 ). , . — .


, 2 ( — )


— . , , , Add 0. 2 1 ( ).


, "" .


, , .


, !


, "Hello World".


"" "" :



" " "" , .


, " "



, "" :


LdConst 0
ArgNum 1
CallLoc 0
End 0

"". , -



?


"" " " v8unpack . 1- . " " "". .



. .


 = 8;
 =  + 2;
 =  - ;

: -, 8 2 "" . 0, — 1. , , . .



08
12


0
1
2

LdVar. , . , :


LineNum 1 ;   
LdVar 0 ;     0 ()
LdConst 0 ;     0 ( 8)
Assign ;  -       , .
LineNum 2 ;   
LdVar 1 ;     1 ()
LdVar 0 ;     0 ()
LdConst 1 ;     1 ( 2)
Add ;  2   ,     (+2)
Assign ;  -       ,  ( = (+2)).
LineNum 3 ;  
LdVar 2 ;   2 ()
LdVar 1 ;   1 ()
LdVar 0 ;   0 ()
Sub; .  2 ,  
Assign;   = (-)
End;   

, , , , . , LineNum? , , , . . , , " , " . , LineNum. , , , .



. -, , . ( ) . :


ArgNum, ( )
CallLoc
CallProc,
CallFunc, ( )
Ret( )
LdRet

. "" . 0.


, LineNum. "" 1 .


LdConst 0;    - 
ArgNum 1;           
CallLoc 0;     0.

, ArgNum. — . , . , .



, ( ), , — - . Assign, . 2 . . LdRet. , , . , Ret, . LdRet — . , . . 1Script "" .



, , . . , . Jmp. , Jmp . . , , 1. - — , .



, , 1 . , " " , — . = , " " . :


 () = ("")  . = 2 

2 : . 1 . , , . , " " .


, . , . 2 — And Or . , , .


, "" , , , .. , .. . ( ). , , , .. , ).


2 : JmpTrue JmpFalse. ( ), , , . , JmpTrue 1 . .. , JmpTrue, , .. 1 (trollface) , 1Script JmpTrue .



? 0 1, 0 1


0: LdVar 0 ;     
1: LdConst 0 ;     1
2: Cmp ;  (     )
3: JmpFalse 6 ;    6,    
4:  IF ;  
5:  IF ;  
6:  … ; 

— . — .



3 : "", "… " " … ". "" , .


"… " " ", , . , , . Gte (--) JmpFalse . , "".


" "


. — , Next()


Iter, Next , . , … , , 1 , , .


. , , :


 ()

         
        .();
    ; 


, "" 0, "" 1. , , "0", . , ? , :)


? , :


PutTmp ;   
LdTmp ;     

( 0)


LdLoc 0 ;    

, , .


Iter ;          -.
Assign ;   Tmp

, :


0LineNum4.
1PutTmp0
2LdTmp0
3LdLoc0. Var
4Iter0
5Assign0= ()
6LineNum4.
7LdLoc2. Var
8LdTmp0
9Assign0= ()
10LdLoc2. Var
11Next0. , , ( — , — )
12JmpFalse26, . Cmd
13LdLoc1. Var
14LdLoc2. Var
15Assign0= ()
16LdLoc2. Var
17LdUndef0
18Assign0= ()
19LineNum5.
20LdLoc1. Var
21ArgNum0(, ). , . , , ( ) ( )
22CallProc0.< >() ( , .. ). Const,
23LineNum5.
24LineNum6.
25Jmp6. Cmd
26PopTmp11? (, - )
27LdLoc2. Var
28LdUndef0
29Assign0= ()
30LdLoc2. Var
31LdUndef0
32Assign0= ()
33LineNum8.
34End0(, )
35End0(, )
36End0(, )

5. Assign, 2 — . .


:


LdLoc 2 ;      0
LdTmp 0 ;    
Assign;     0
LdLoc 2;   0  
Next;        
JmpFalse 26 ;     -      .

Next. , (0), , , , , . JmpFalse .


, JmpFalse 0 , . 0, 0 — .


- . 19-23 . 25 — Jmp , 26 — .


27- 32-. 0, - 2 . , , … , +3 , 0 . , , …


, 1Script :


0  :(LineNum     3)
1  :(PushLoc     0)
2  :(PushIterator  0)
3  :(LineNum     3)
4  :(IteratorNext  0)
5  :(JmpFalse   12)
6  :(LoadLoc     1)
7  :(LineNum     4)
8  :(PushLoc     1)
9  :(ArgNum      0)
10 :(ResolveMethodProc  0)
11 :(Jmp         3)
12 :(StopIterator  0)
13 :(PushConst   1)
14 :(Return      0)

15 37. , .. , . , 1Script 1. .



, , , . ? , , . , .


? , , , "" "".


- , 1 . BlckEnd Jmp . , BlckEnd — - . BlckEnd 0.


. "" BlckEnd, .


 // 1
     // 2
         // 3
             2; // BlckEnd 3

.. "" — BlckEnd 0, "" — BlckEnd < >. , " " , , .. "" " ".


-


BeginTry, . .. . , , BlckEnd <> Jmp ;


:


 ()
    
       ;
    
       ;
    ;


0: BeginTry 4 ;    Cmd  
1: LineNum 6 ;    
2:BlckEnd 1 ;    1
3:Jmp 6 ;   
4:LineNum 6 ;  :    
5:EndTry 0 ; (  )
6:LineNum 7 ;  :    
7:End 0 ;  (, )
8:End 0 ;  (, )
9:End 0 ;  (, ) 

. BeginTry , , ( ).


( ), BlckEnd ( 2-3). EndTry.


, , . .



? , ? , "" "". image -, , v8unpack epf.


, .


: . , . , (-) , ? , " " :


 = .();

 .() 
    (.);
;

, , " " "-()". 1 , 1 , !


. "" "" . , "" — . :


LdVar 0-
ArgNum 0()
New 0, 0
Assign
LdVar 0
Iter
,
ArgNum 1,
CallLoc 0
End

"". "". ? , "(())" "". - -. ? — !


(dmpas), , :)


Disclaimer


, , . , , 1 . , . "" . , . . , "" , .



1C est un système complexe et multicouche et il est extrêmement intéressant de l'étudier. Et mieux vous savez comment fonctionne votre système, plus vous pouvez l'utiliser efficacement. Aujourd'hui, nous avons examiné le fonctionnement de la machine virtuelle 1C et, espérons-le, élargi nos horizons techniques. Eh bien, et d'ailleurs, nous avons mis la main sur un jouet de construction, parce que jouer avec l'assembleur est assez amusant!


Je vous souhaite un succès créatif!


All Articles