1C: Assembler - write a clean bytecode for the stacked machine 1C: Enterprise


Stack machines are used in a wide variety of modern programming languages. They are easy to understand and at the same time quite effective. Want to try one such in action?


All of you, probably, have heard that 1C-nicknames complain about their system, considering the 1C language is not low enough, boring, etc. All of them look longingly toward the "real" programming languages. So, gentlemen, they are wrong. In the 1C system there are places where you can stretch the programmer’s brain and enjoy the low-level technology. I suggest you dive into the bowels of the 1C virtual machine and understand how it works. It has its own β€œassembler” and today we will write working code for 1C on it. Come under the cut, it will be fun!


Stacked Virtual Machines


Dynamic programming languages ​​are increasingly capturing the world. From the "honest" native languages ​​in the ranks, perhaps, only C remained (with pluses and without). This is if we take the industrial mainstream. All popular languages, one way or another, have a layer in the form of a "runtime environment" or a "virtual machine", which provides code execution on a particular architecture of iron. And the vast majority of these "virtual machines" are stacked, i.e. implement processing operations using such a structure known in the computer world as the "stack".


Remark for those who have forgotten


(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 is a complex and multi-layer system and it is extremely interesting to study it. And the better you know how your system works, the more efficient you can use it. Today we examined how the 1C virtual machine works and, hopefully, expanded our technical horizons. Well, and besides, we got our hands on a construction toy, because playing with assembler is pretty fun!


I wish you creative success!


All Articles