1C: Assembler - escreva um bytecode limpo para a máquina empilhada 1C: Enterprise


Máquinas de empilhar são usadas em uma ampla variedade de linguagens de programação modernas. Eles são fáceis de entender e ao mesmo tempo bastante eficazes. Deseja experimentar um desses em ação?


Todos vocês provavelmente já ouviram dizer que os apelidos 1C se queixam de seu sistema, considerando que o idioma 1C não é baixo o suficiente, chato etc. Todos eles olham ansiosamente para as linguagens de programação "reais". Então, senhores, eles estão errados. No sistema 1C, há lugares onde você pode esticar o cérebro do programador e aproveitar a tecnologia de baixo nível. Sugiro que você mergulhe nas entranhas da máquina virtual 1C e entenda como ela funciona. Ele tem seu próprio "assembler" e hoje escreveremos o código de trabalho para 1C nele. Venha para o corte, será divertido!


Máquinas virtuais empilhadas


Linguagens de programação dinâmicas estão cada vez mais capturando o mundo. Das línguas nativas "honestas" nas fileiras, talvez, apenas C permanecesse (com vantagens e sem). Isto é, se tomarmos o mainstream industrial. Todas as linguagens populares, de uma maneira ou de outra, têm uma camada na forma de um "ambiente de tempo de execução" ou uma "máquina virtual", que fornece execução de código em uma arquitetura específica do iron. E a grande maioria dessas "máquinas virtuais" está empilhada, ou seja, implementar operações de processamento usando uma estrutura conhecida no mundo dos computadores como a "pilha".


Observação para quem esqueceu


(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 . , . "" . , . . , "" , .



O 1C é um sistema complexo e multicamada e é extremamente interessante estudá-lo. E quanto melhor você souber como seu sistema funciona, mais eficiente poderá usá-lo. Hoje examinamos como a máquina virtual 1C funciona e, esperamos, expandimos nossos horizontes técnicos. Bem, e além disso, colocamos nossas mãos em um brinquedo de construção, porque brincar com montador é muito divertido!


Desejo-lhe sucesso criativo!


All Articles