ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ β ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°, ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΡΡΠ°Ρ Π½Π°ΠΏΠΈΡΠ°Π½Π½ΡΠΉ Π½Π° ΡΠ·ΡΠΊΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ΅ΠΊΡΡ Π² Π±ΠΈΠ½Π°ΡΠ½ΡΠΉ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ». Π ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ β Ρ ReverseLang Π² ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ELF ΡΠ°ΠΉΠ» Π΄Π»Ρ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΡ amd64. Π‘ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠΎΠΌ ReverseLang ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡ Π² ΡΠ°Π·Π΄Π΅Π»Π΅ Ρ ΠΊΡΠ°ΡΠΊΠΎΠΉ ΡΠΏΡΠ°Π²ΠΊΠΎΠΉ.
ΠΠ»Ρ ΡΠ±ΠΎΡΠΊΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ° Π²ΡΠΏΠΎΠ»Π½ΠΈΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ:
$ git clone https:/foxidokun/x64_compiler # Π‘ΠΊΠ»ΠΎΠ½ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ
$ cd x64_compiler && make all # Π‘ΠΎΠ±ΡΠ°ΡΡ Π²ΡΠ΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΠ΅ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΊΠΈ
Π’Π΅ΠΏΠ΅ΡΡ Π΄Π»Ρ ΡΠ±ΠΎΡΠΊΠΈ ReverseLang Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠΊΡΠΈΠΏΡΠΎΠΌ compile.sh
, ΠΏΠ΅ΡΠ΅Π΄Π°Π² Π΅ΠΌΡ Π΄Π²Π° Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° β ΡΠ°ΠΉΠ» Ρ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ Π½Π° ΡΠ·ΡΠΊΠ΅ Reverselang ΠΈ ΠΏΡΡΡ, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΡΠΎΡ
ΡΠ°Π½ΡΡΡ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ».
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΠΎΠ±Ρ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΠΈ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΠΎΠ³ΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΡ Π² examples/
:
$ ./compile.sh examples/quad.edoc /tmp/quad.bin
$ /tmp/quad.bin
INPUT: 1 # Π Π΅ΡΠ°Π΅ΠΌ x^2-4x+3 = 0
INPUT: -4
INPUT: 3
OUTPUT: 2.00 # 2 roots
OUTPUT: 1.00 # x = 1
OUTPUT: 3.00 # x = 3
- ΠΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΈΠΌΠ΅ΡΡ ΠΎΠ΄ΠΈΠ½ ΡΠΈΠΏ β Π·Π½Π°ΠΊΠΎΠ²ΡΠ΅ 64-Π±ΠΈΡΠ½ΡΠ΅ ΡΠΈΡΠ»Π°.
- ΠΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈΠΌΠ΅ΡΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅.
- Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΡΠ·ΡΠΊΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ 3 ΡΡΠ½ΠΊΡΠΈΠΈ:
input / output / sqrt
. - Π‘ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΌΠ°ΡΠ΅ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ:
+, -, /, *
. - ΠΠΎΡΡΡΠΏΠ½Ρ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ:
>, >=, <, <=
, Π° ΡΠ°ΠΊΠΆΠ΅ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π/ΠΠΠ (&& ΠΈ ||
) ΠΈ ΠΎΡΡΠΈΡΠ°Π½ΠΈΠ΅ (!
). - Π ΡΠ·ΡΠΊΠ΅ Π΅ΡΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° ΡΡΠ½ΠΊΡΠΈΠΉ, ΡΠΈΠΊΠ»ΠΎΠ² while ΠΈ if-else Π±Π»ΠΎΠΊΠΎΠ².
ΠΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠ°
Program ::= PROG_BEG (SubProgram | Func)* PROG_END
Func ::= L_BRACKET (NAME (SEP NAME)) R_BRACKET NAME FN FUNC_OPEN_BLOCK Subprogram FUNC_CLOSE_BLOCK
SubProgram ::= (FlowBlock)+
FlowBlock ::= IfBlock | WhileBlock | OPEN_BLOCK Body CLOSE_BLOCK | Body
WhileBlock ::= L_BRACKET Expression R_BRACKET WHILE OPEN_BLOCK Body CLOSE_BLOCK
IfBlock ::= L_BRACKET Expression R_BRACKET IF OPEN_BLOCK Body CLOSE_BLOCK (ELSE OPEN_BLOCK Body CLOSE_BLOCK)
Body ::= (Line)+
Line ::= BREAK Expression RETURN | BREAK Expression (= NAME (LET))
Expression ::= OrOperand (|| OrOperand)+
OrOperand ::= AndOperand (&& AndOperand)+
AndOperand ::= CompOperand (<=> CompOperand)
CompOperand ::= AddOperand ([+-] AddOperand)*
AddOperand ::= MulOperand ([/ *] MulOperand )*
MulOperand ::= GeneralOperand (NOT)
GeneralOperand ::= Quant | L_BRACKET Expression R_BRACKET
Quant ::= VAR | VAL | INPUT | BuiltInFunc | L_BRACKET (Expression (SEM Expression)) R_BRACKET NAME
BuiltInFunc ::= L_BRACKET Expression R_BRACKET (PRINT|SQRT|SIN)
Π‘ΠΈΠ½ΡΠ°ΠΊΡΠΈΡ ReverseLang ΡΠ²Π»ΡΠ΅ΡΡΡ C-ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠΌ Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΡΡ: ΠΊΠ°ΠΆΠ΄ΡΡ ΡΡΡΠΎΠΊΡ ΡΡΠΎΠΈΡ ΡΠΈΡΠ°ΡΡ ΡΠΏΡΠ°Π²Π° Π½Π°Π»Π΅Π²ΠΎ. Π’Π°ΠΊ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄ Π½Π° C
int func (int a, int b, int c) {
int d = a / b;
if (a > b) {
return c;
} else {
return d;
}
}
Π½Π° ReverseLang ΠΏΡΠΈΠΌΠ΅Ρ Π²ΠΈΠ΄
(c, b, a) func fn
[
; b / a = d let
(b > a) if
{
; c return
} else {
; d return
}
]
ΠΠΎΠ»Π½ΡΡ Π²Π΅ΡΡΠΈΡ ΡΡΠΎΠ³ΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠ°, ΠΊΠ°ΠΊ ΠΈ ΠΎΡΡΠ°Π»ΡΠ½ΡΡ
, ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ examples/
ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΡΠ°Π·Π±ΠΈΡ Π½Π° ΡΡΠΈ ΠΊΠ»ΡΡΠ΅Π²ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°, ΠΏΠΎΡΡΠ°ΠΏΠ½ΠΎ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΠΈΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π³ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΠΎΠ΅ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π΄Π΅ΡΠ΅Π²ΠΎ (abstract syntax tree, AST). Π ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΌ Π΄Π΅ΡΠ΅Π²Π΅ Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΠ΅ Π²Π΅ΡΡΠΈΠ½Ρ ΡΠΎΠΏΠΎΡΡΠ°Π²Π»Π΅Π½Ρ Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ°ΠΌΠΈ ΡΠ·ΡΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π° Π»ΠΈΡΡΡΡ β Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌΠΈ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Π°ΠΌΠΈ. ΠΡΠΈΠΌΠ΅Ρ ΡΠ°ΠΊΠΎΠ³ΠΎ Π΄Π΅ΡΠ΅Π²Π° ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ Π² ΠΊΠΎΠ½ΡΠ΅ ΡΡΠΎΠ³ΠΎ ΡΠ°Π·Π΄Π΅Π»Π°.
Π€ΡΠΎΠ½ΡΠ΅Π½Π΄
- ΠΠ΅ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ· ΡΠ°Π·Π±ΠΈΠ²Π°Π΅Ρ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ Π½Π° Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΊΠ²Π°Π½ΡΡ (Π»Π΅ΠΊΡΠ΅ΠΌΡ) β ΡΠΈΡΠ»Π°, ΠΊΠ»ΡΡΠ΅Π²ΡΠ΅ ΡΠ»ΠΎΠ²Π°, ΠΈΠΌΠ΅Π½Π° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΉ.
- Π‘ΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ· ΡΠΎΠ±ΠΈΡΠ°Π΅Ρ ΠΈΠ· Π»Π΅ΠΊΡΠ΅ΠΌ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΠΈ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈ ΡΠΈΠΊΠ»Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π°Π»Π³ΠΎΡΠΈΡΠΌ ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΡΠΏΡΡΠΊΠ°.
- Π ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΡΠΏΡΡΠΊΠ° ΡΡΡΠΎΠΈΡΡΡ Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΠΎΠ΅ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π΄Π΅ΡΠ΅Π²ΠΎ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΈ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΈΡΠΎΠ³ΠΎΠ²ΡΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ ΡΠ°Π±ΠΎΡΡ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π°.
ΠΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΠΉ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΎΡ (middleend)
ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΎΡ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π½Π° Π²Ρ ΠΎΠ΄ AST ΠΈ ΠΏΡΡΠ°Π΅ΡΡΡ ΡΠΏΡΠΎΡΡΠΈΡΡ Π΅Π³ΠΎ, Π½Π΅ Π½Π°ΡΡΡΠ°Ρ ΠΏΡΠΈ ΡΡΠΎΠΌ Π»ΠΎΠ³ΠΈΠΊΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. Π Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΈΠ· ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΉ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ½ΡΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ: ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ² ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΡ ΠΈΠ· ΠΌΠ°ΡΠ΅ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΈΠ»ΠΈ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Π½Π°Π΄ ΡΠΈΡΠ»Π°ΠΌΠΈ, ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΎΡ Π²ΡΡΠΈΡΠ»ΡΠ΅Ρ Π΅Π΅ ΠΈ Π·Π°ΠΌΠ΅Π½ΡΠ΅Ρ Π½Π° ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ.
ΠΡΠΊΠ΅Π½Π΄
ΠΡΠΊΠ΅Π½Π΄ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π½Π° Π²Ρ ΠΎΠ΄ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ΅ AST Π΄Π΅ΡΠ΅Π²ΠΎ ΠΈ, ΠΎΠ±Ρ ΠΎΠ΄Ρ Π΅Π³ΠΎ Π² postorder ΠΏΠΎΡΡΠ΄ΠΊΠ΅, Π³Π΅Π½Π΅ΡΠΈΡΠ΅Ρ ΠΌΠ°ΡΠΈΠ½Π½ΡΠΉ ΠΊΠΎΠ΄ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π²Π΅ΡΡΠΈΠ½Ρ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΊΠΎΠ΄Π° Π»ΡΠ±ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΊΠΎΠ΄ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Π΅Π΅ ΠΎΠΏΠ΅ΡΠ°Π½Π΄ΠΎΠ² ΡΠΆΠ΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½.
Π’Π°ΠΊΠ°Ρ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΠΈΠ΅ ΠΊΡΡΠΊΠΈ ΠΏΡΠΈ Π°Π΄Π°ΠΏΡΠ°ΡΠΈΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ° ΠΏΠΎΠ΄ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠ·ΡΠΊΠΈ ΠΈΠ»ΠΈ ΠΏΠΎΠ΄
Π΄ΡΡΠ³ΠΈΠ΅ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΡ. Π’Π°ΠΊ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ·ΡΠΊΠ° ΠΏΠΎΠ΄ x64
ΠΈ arm
ΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΠΈΠ΅
ΡΡΠΎΠ½ΡΠ΅Π½Π΄ ΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΎΡ, Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΡ Π΄Π²ΡΡ
ΡΠ°Π·Π½ΡΡ
ΡΠ·ΡΠΊΠΎΠ² ΠΏΠΎΠ΄ ΠΎΠ΄Π½Ρ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΡ ΠΌΠΎΠ³ΡΡ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΎΡ ΠΈ Π±ΡΠΊΠ΅Π½Π΄.
Π Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Ρ ΡΠ·ΡΠΊΠΎΠ² ICPC ΠΈ kaban54's lang ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½Ρ Π² ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠ΅ Ρ ReverseLang ΠΈ ΠΈΠΌΠ΅ΡΡ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠΉ ΡΠΎΡΠΌΠ°Ρ AST, ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π±ΡΠΊΠ΅Π½Π΄Π° ReverseLang.
ΠΠΎΠ΄ΠΎΠ±Π½Π°Ρ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΠΌ-ΡΠΎ Π½ΠΎΠ²ΡΠΌ ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π² ΡΠ΅ΠΌΠ΅ΠΉΡΡΠ²Π΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠΎΠ² GCC
, Π° ΡΠ°ΠΊΠΆΠ΅ Π² ΠΎΡΠ½ΠΎΠ²Π°Π½Π½ΡΡ
Π½Π° llvm
ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ°Ρ
, ΠΏΡΠ°Π²Π΄Π° Π² Π½ΠΈΡ
Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅
Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π³ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π²ΠΌΠ΅ΡΡΠΎ AST.
ΠΡΠΈΠΌΠ΅Ρ AST
ΠΠΎΡΡΡΠΎΠΈΠΌ AST Π΄Π»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΈΠ· ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠΏΡΠ°Π²ΠΊΠΈ:
ΠΠΎΠ»Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΏΡΠΈΠΌΠ΅ΡΠ°
~sya~
(x) print fn
[
; (x) __builtin_print__ return
]
(c, b, a) func fn
[
; b / a = d let
(b > a) if
{
; c return
} else {
; d return
}
]
; (1, 2, 3) func = ans let
; (ans) print
~nya~
ΠΠΈΠ·ΡΠ°Π»ΠΈΠ·Π°ΡΠΈΡ AST Π΄Π»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΈΠ· ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠΏΡΠ°Π²ΠΊΠΈ
Π‘Π°ΠΌ Π±ΡΠΊΠ΅Π½Π΄ ΡΠ°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΡ ΡΡΡΡΠΊΡΡΡΡ. ΠΡΠΎΡΠ΅ΡΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ AST Π² ΠΌΠ°ΡΠΈΠ½Π½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ°Π·Π±ΠΈΡ Π½Π° ΡΡΠΈ ΡΡΠ°ΠΏΠ°:
- AST ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅ΡΡΡ Π² Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ (Backend IR) β ΠΌΠ°ΡΡΠΈΠ² ΡΡΡΡΠΊΡΡΡ, ΡΠ²Π»ΡΡΡΠΈΡ ΡΡ Π°ΡΡΠ΅ΠΌΠ±Π»Π΅ΡΠ½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ Π΄Π»Ρ Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΠΎΠ³ΠΎ ΡΡΠ΅ΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ° (ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ Π΄Π°Π»Π΅Π΅ Π² ΡΠ΅ΠΊΡΠΈΠΈ Backend IR).
- ΠΠΎΡΠ»Π΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ IR ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΠ°ΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΎΠ½Π½ΡΠ΅ ΠΏΡΠΎΡ
ΠΎΠ΄Ρ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ±ΠΈΡΠ°ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΡΠ΅
push / pop
(backend optimisations). ΠΠ΄Π½Π°ΠΊΠΎ Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ Π² Π±ΡΠΊΠ΅Π½Π΄Π΅ Π½Π΅ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ. - ΠΠ°Π»Π΅Π΅ ΡΡΠΎΡ IR ΡΡΠ°Π½ΡΠ»ΠΈΡΡΠ΅ΡΡΡ Π² ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π΄Π»Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΉ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°.
ΠΡΠΈ ΡΡΠΎΠΌ ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π΄Π»Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ Π°Π΄ΡΠ΅ΡΠΎΠ² ΠΌΠ΅ΡΠΎΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π²ΡΡ ΠΏΡΠΎΡ ΠΎΠ΄Π½Π°Ρ ΡΡ Π΅ΠΌΠ° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ (multi-pass compiler), ΡΠΎ ΡΡΠ°ΠΏΡ 1 ΠΈ 3 Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π΄Π²Π° ΡΠ°Π·Π°.
ΠΡΠΊΠ΅Π½Π΄ ΠΏΠΎΡΡΡΠΎΠ΅Π½ Π½Π° ΡΠ΅Ρ ΠΆΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ½ΡΡ ΠΏΡΠΈΠ½ΡΠΈΠΏΠ°Ρ , ΡΡΠΎ ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π² ΡΠ΅Π»ΠΎΠΌ β ΡΠ°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ Π½Π° ΡΡΠ°ΠΏΡ Π΄Π»Ρ ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ. Backend IR ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΠΈΡΡ ΡΡΠ°Π½ΡΠ»ΡΡΠΈΡ AST Π² Π½Π°Π±ΠΎΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΡΠ½ΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ Π΄Π»Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΡΡ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡ ΡΡ ΠΎΠΆΠ΅Π³ΠΎ ΡΠΈΠΏΠ° ΠΈΠ»ΠΈ Π΄Π»Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ Π²ΡΡ ΠΎΠ΄Π½ΡΡ ΡΠΎΡΠΌΠ°ΡΠΎΠ². Π’Π°ΠΊ, ΠΏΠΎΠΌΠΈΠΌΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ Π² Π±ΠΈΠ½Π°ΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» Π΄Π°Π½Π½ΡΠΉ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΡΠΌΠ΅Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π² JIT ΡΠ΅ΠΆΠΈΠΌΠ΅ Ρ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΌ Π΄ΡΠ±Π»ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π°.
Π Π΄Π°Π½Π½ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ΅ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ IR ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠ²ΡΠ·Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ ΡΡΡΡΠΊΡΡΡ
struct instruction_t {
instruction_type_t type; // Π’ΠΈΠΏ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ β push / add / call / etc
struct { // ΠΠ°ΠΊΠΈΠ΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ ΡΡΠ΅Π±ΡΡΡΡΡ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ
unsigned char need_imm_arg: 1; // - ΠΠΎΠ½ΡΡΠ°Π½ΡΠ°
unsigned char need_reg_arg: 1; // - Π Π΅Π³ΠΈΡΡΡ
unsigned char need_mem_arg: 1; // - ΠΠ·Π²Π»Π΅ΠΊΠ°Π΅ΡΡΡ Π»ΠΈ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ ΠΈΠ· ΠΏΠ°ΠΌΡΡΠΈ
};
unsigned char reg_num; // ΠΠΎΠΌΠ΅Ρ ΡΠ΅Π³ΠΈΡΡΡΠ°-Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° (Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ)
uint64_t imm_arg; // ΠΠΎΠ½ΡΡΠ°Π½ΡΠ½ΡΠΉ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ (Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ)
size_t index; // ΠΠΎΠΌΠ΅Ρ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π² IR
instruction_t *next; // Π£ΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΡΡ ΡΡΡΡΠΊΡΡΡΡ
};
ΠΡΠΈ ΡΡΠΎΠΌ IR ΡΠ°ΡΡΡΠΈΡΠ°Π½ Π½Π° Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΡΠΉ ΡΡΠ΅ΠΊΠΎΠ²ΡΠΉ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡ, Π° ΠΏΠΎΡΠΎΠΌΡ ΠΈΠΌΠ΅Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ:
ΠΠΎΠΌΠ°Π½Π΄Π° | ΠΠ΅ΠΉΡΡΠ²ΠΈΠ΅ |
---|---|
push imm/reg/mem |
ΠΠΎΠ»ΠΎΠΆΠΈΡΡ Π² ΡΡΠ΅ΠΊ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ, Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ· ΡΠ΅Π³ΠΈΡΡΡΠ° ΠΈΠ»ΠΈ ΠΈΠ· ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΠΎ Π°Π΄ΡΠ΅ΡΡ reg + imm , Π³Π΄Π΅ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΎΠΏΠ΅ΡΠ°Π½Π΄ΠΎΠ² (reg ΠΈΠ»ΠΈ imm ) ΠΎΠΏΡΠΈΠΎΠ½Π°Π»Π΅Π½. |
pop reg/mem |
ΠΠ·Π²Π»Π΅ΡΡ ΠΈΠ· ΡΡΠ΅ΠΊΠ° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΡ Π΅Π³ΠΎ Π² ΡΠ΅Π³ΠΈΡΡΡ ΠΈΠ»ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΡΡ ΠΏΠ°ΠΌΡΡΡ |
add/sub/mul/div |
ΠΡΠΈΡΠΌΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Ρ Π΄Π²ΡΠΌΡ Π²Π΅ΡΡ Π½ΠΈΠΌΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ Π½Π° ΡΡΠ΅ΠΊΠ΅ (Π²Π΅ΡΡ Π½ΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΡΠ΅ΠΊΠ° ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΡΠ°Π²ΡΠΌ ΠΎΠΏΠ΅ΡΠ°Π½Π΄ΠΎΠΌ) |
sqrt / sin / cos |
ΠΡΠΈΡΠΌΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Ρ ΠΎΠ΄ΠΈΠ½ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠΌ Π½Π° ΡΡΠ΅ΠΊΠ΅ |
call/jmp/j?? imm |
Π‘ΠΎΠ²Π΅ΡΡΠΈΡΡ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ Π½Π° Π°Π΄ΡΠ΅Ρ (Π½ΠΎΠΌΠ΅Ρ ΡΡΡΡΠΊΡΡΡΡ Π² IR). j?? ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ ΡΡΠ»ΠΎΠ²Π½ΡΠ΅ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Ρ (ja, jae, jb, jbe, je, jne ) |
inp / out |
ΠΠ²ΠΎΠ΄ / Π²ΡΠ²ΠΎΠ΄ Π²Π΅ΡΡ Π½Π΅Π³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΡΡΠ΅ΠΊΠ° |
ret |
ΠΠΎΠΌΠ°Π½Π΄Π° Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΎΠ±ΡΠ°ΡΠ½Π°Ρ ΠΊ call |
halt |
ΠΠ°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, Π°Π½Π°Π»ΠΎΠ³ ΡΡΠ½ΠΊΡΠΈΠΈ abort() Π² C |
ΠΡΠΈ ΡΡΠΎΠΌ Π²ΡΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΠΏΠΎΠ³Π»ΠΎΡΠ°ΡΡ ΡΠ²ΠΎΠΈ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Ρ, Π΅ΡΠ»ΠΈ ΡΠ°ΠΊΠΎΠ²ΡΠ΅ ΠΈΠΌΠ΅ΡΡΡΡ, ΠΈ ΠΏΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊΠ»Π°Π΄ΡΡ Π΅Π³ΠΎ Π½Π° Π²Π΅ΡΡ ΡΡΠΊΡ ΡΡΠ΅ΠΊΠ°.
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ELF ΡΠ°ΠΉΠ», ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ ΠΎΡΡΡΠ°Π½ΡΠ»ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΈ ΠΊΠΎΠ΄ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ.
ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π² ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ°Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ:
- ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ELF ΡΠ°ΠΉΠ»Π° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΎΠ±ΡΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΏΡΠΎ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΊ: ΡΡΠ΅Π±ΡΠ΅ΠΌΡΡ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°, Π°Π΄ΡΠ΅Ρ Π²Ρ ΠΎΠ΄Π°, ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΈ ΠΌΠ΅ΡΡΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅Π³ΠΌΠ΅Π½ΡΠ½ΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ².
const Elf64_Ehdr ELF_HEADER = {
.e_ident = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, // Magic signature
ELFCLASS64, // 64-bit system
ELFDATA2LSB, // LittleEndian / BigEndian
EV_CURRENT, // Version = Current
ELFOSABI_NONE, // Non specified system
0
},
.e_type = ET_EXEC, // File type = Executable
.e_machine = EM_X86_64, // Arch = amd64
.e_version = EV_CURRENT, // Version = Current
.e_entry = 0x402000, // Fixed entry addr
.e_phoff = sizeof(Elf64_Ehdr), // Offset of program header table. We took size of elf header
.e_shoff = 0, // Offset of segment header table. Not used => 0
.e_flags = 0, // Extra flags: no flags
.e_ehsize = sizeof(Elf64_Ehdr), // Size of this header.
.e_phentsize = sizeof(Elf64_Phdr), // Size of Program header table entry.
.e_phnum = NUM_PHEADERS, // Number of pheader entries. (system + stdlib + code + ram)
.e_shentsize = sizeof(Elf64_Shdr), // Size of Segment header entry.
.e_shnum = 0, // Number of segments in programm.
.e_shstrndx = 0, // Index of string table. (Explained in further parts).
};
- ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΡΠ΅Π³ΠΌΠ΅Π½ΡΠΎΠ² ΡΠΎΠ΄Π΅ΡΠΆΠ°Ρ Π΄Π΅ΡΠ°Π»ΡΠ½ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΏΡΠΎ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ΅Π³ΠΌΠ΅Π½Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ: ΠΏΡΠ°Π²Π° Π΄ΠΎΡΡΡΠΏΠ°, ΠΌΠ΅ΡΡΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΡΠ°Π·ΠΌΠ΅Ρ Π² ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠΌ ΡΠ°ΠΉΠ»Π΅, Π° ΡΠ°ΠΊΠΆΠ΅ Π°Π΄ΡΠ΅Ρ, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π΅Π³ΠΎ ΡΠ»Π΅Π΄ΡΠ΅Ρ Π·Π°Π³ΡΡΠΆΠ°ΡΡ. ΠΠ°Π½Π½ΡΠΉ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π»ΠΈΡΡ 4 ΡΠ΅Π³ΠΌΠ΅Π½ΡΠ°:
- Π‘Π»ΡΠΆΠ΅Π±Π½ΡΠΉ ΡΠ΅Π³ΠΌΠ΅Π½Ρ
Elf64_Phdr SYSTEM_PHEADER = {
.p_type = PT_LOAD,
.p_flags = PF_R , /* read */
.p_offset = 0 , /* (bytes into file) */
.p_vaddr = 0x400000 , /* (virtual addr at runtime) */
.p_paddr = 0x400000 , /* (physical addr at runtime) */
.p_filesz = sizeof(Elf64_Ehdr) + NUM_PHEADERS * sizeof(Elf64_Phdr), /* (bytes in file) */
.p_memsz = sizeof(Elf64_Ehdr) + NUM_PHEADERS * sizeof(Elf64_Phdr), /* (bytes in mem at runtime) */
.p_align = 4096 , /* (min mem alignment in bytes) */
};
ΠΠ°Π½Π½ΡΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΏΡΠΈΡΡΡΡΡΠ²ΡΠ΅Ρ Π²ΠΎ Π²ΡΠ΅Ρ
ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΡ
ELF ΡΠ°ΠΉΠ»Π°Ρ
ΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ Π²ΡΡ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΏΠΎ Π°Π΄ΡΠ΅ΡΡ 0x400000
Ρ ΠΏΡΠ°Π²Π°ΠΌΠΈ Π»ΠΈΡΡ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅.
- Π‘Π΅Π³ΠΌΠ΅Π½Ρ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ
Elf64_Phdr STDLIB_PHEADER = {
.p_type = PT_LOAD,
.p_flags = PF_R | PF_X, /* Read & Execute */
.p_offset = 4096, /* (bytes into file) */
.p_vaddr = 0x401000, /* (virtual addr at runtime) */
.p_paddr = 0x401000, /* (physical addr at runtime) */
.p_filesz = x64::STDLIB_SIZE, /* (bytes in file) */
.p_memsz = x64::STDLIB_SIZE, /* (bytes in mem at runtime) */
.p_align = 4096, /* (min mem alignment in bytes) */
};
ΠΠ»Ρ ΠΏΡΠΎΡΡΠΎΡΡ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΡΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π·Π°Π³ΡΡΠΆΠ°Π΅ΡΡΡ Π² ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΠ΅Π³ΠΌΠ΅Π½Ρ ΠΏΠΎ Π°Π΄ΡΠ΅ΡΡ 0x403000
Ρ ΠΏΡΠ°Π²Π°ΠΌΠΈ Π½Π° ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΊΠΎΠ΄ ΠΈΠ· ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ Π½Π΅ ΠΊΠΎΠΏΠΈΡΡΠ΅ΡΡΡ, Π° Π»ΠΈΡΡ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΡΡΡ Π² Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΡ ΠΏΠ°ΠΌΡΡΡ, ΡΠΎ Π²ΡΠ΅ ΡΠ΅Π³ΠΌΠ΅Π½ΡΡ ΠΎΠ±ΡΠ·Π°Π½Ρ
Π½Π°ΡΠΈΠ½Π°ΡΡΡΡ Ρ Π°Π΄ΡΠ΅ΡΠΎΠ², ΠΊΡΠ°ΡΠ½ΡΡ
ΡΠ°Π·ΠΌΠ΅ΡΡ ΡΡΡΠ°Π½ΠΈΡΡ β 4096 Π±Π°ΠΉΡ. ΠΠΎΡΡΠΎΠΌΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π²ΡΠ½ΡΠΆΠ΄Π΅Π½Π½ΠΎ Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π² Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΊ Π½Π°ΡΠΈΠ½Π°Ρ Ρ
4096 Π±Π°ΠΉΡΠ° (.p_offset
), Π° Π½Π΅ ΡΡΠ°Π·Ρ ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΌΠ΅Π½ΡΠ½ΡΡ
Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ².
- Π‘Π΅Π³ΠΌΠ΅Π½Ρ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°
Π‘Π΅Π³ΠΌΠ΅Π½Ρ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΠΎΡΠ»ΠΈΡΠ°Π΅ΡΡΡ ΠΎΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π»ΠΈΡΡ Π°Π΄ΡΠ΅ΡΠΎΠΌ Π·Π°Π³ΡΡΠ·ΠΊΠΈ β 0x402000
, ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠΈΠΌ
Ρ Π°Π΄ΡΠ΅ΡΠΎΠΌ Π²Ρ
ΠΎΠ΄Π° ΠΈΠ· ELF Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° (ΠΏΠΎΠ»Π΅ .e_entry
). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΏΠΎΡΠ»Π΅ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ELF ΡΠ°ΠΉΠ»Π° Π² ΠΏΠ°ΠΌΡΡΡ Π½Π°ΡΠΈΠ½Π°Π΅Ρ
ΠΈΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΡΠΎΡ ΡΠ΅Π³ΠΌΠ΅Π½Ρ.
- Π‘Π΅Π³ΠΌΠ΅Π½Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ
ΠΠ»Π°Π²Π½ΠΎΠ΅ ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΡΠ΅Π³ΠΌΠ΅Π½ΡΠ° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ ΠΎΡ ΠΎΡΡΠ°Π»ΡΠ½ΡΡ
β ΠΎΠ½ Π½Π΅ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ ΠΌΠ΅ΡΡΠ° Π½Π° Π΄ΠΈΡΠΊΠ΅. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΏΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠ΅ ELF ΡΠ°ΠΉΠ»Π°
ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠ°ΠΌΠ° Π²ΡΠ΄Π΅Π»ΠΈΡ ΠΎΠ±Π»Π°ΡΡΡ ΠΏΠ°ΠΌΡΡΠΈ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ° ΠΈ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ Π΅Π΅ Π½ΡΠ»ΡΠΌΠΈ. ΠΡΡΠ°ΠΆΠ°Π΅ΡΡΡ ΡΡΠΎ Π² Π½ΡΠ»Π΅Π²ΠΎΠΌ ΠΏΠΎΠ»Π΅
.p_filesz
, ΠΎΡΠ²Π΅ΡΠ°ΡΡΠΈΠΌ Π·Π° ΡΠ°Π·ΠΌΠ΅Ρ ΡΠ΅Π³ΠΌΠ΅Π½ΡΠ° Π² ΡΠ°ΠΉΠ»Π΅, ΠΈ Π½Π΅Π½ΡΠ»Π΅Π²ΠΎΠΌ .p_memsz
, ΠΎΡΠ²Π΅ΡΠ°ΡΡΠΈΠΌ Π·Π° ΡΠ°Π·ΠΌΠ΅Ρ ΠΏΠΎΡΠ»Π΅ Π·Π°Π³ΡΡΠ·ΠΊΠΈ.
const Elf64_Phdr BSS_PHEADER = {
.p_type = PT_LOAD,
.p_flags = PF_R | PF_W,
.p_offset = 0, /* (bytes into file) */
.p_vaddr = 0x405000, /* (virtual addr at runtime) */
.p_paddr = 0x405000, /* (physical addr at runtime) */
.p_filesz = 0, /* (bytes in file) */
.p_memsz = x64::RAMSIZE, /* (bytes in mem at runtime) */
.p_align = 4096, /* (min mem alignment in bytes) */
};
Π ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅ ReverseLang ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ β Π²Π²ΠΎΠ΄/Π²ΡΠ²ΠΎΠ΄, ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΠ΅ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΠΎΠ³ΠΎ ΠΊΠΎΡΠ½Ρ ΠΈ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ (Π΄Π»Ρ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ halt).
ΠΠ°Π½Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π°ΠΏΠΈΡΠ°Π½Ρ Π½Π° Π°ΡΡΠ΅ΠΌΠ±Π»Π΅ΡΠ΅ Ρ ΠΏΡΡΠΌΡΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ
Π²ΡΠ·ΠΎΠ²ΠΎΠ², ΡΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ
Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠΈ Ρ glibc ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎΠ³ΠΎ ΡΡΠ»ΠΎΠΆΠ½Π΅Π½ΠΈΡ ΡΡΡΡΠΊΡΡΡΡ ELF ΡΠ°ΠΉΠ»Π°. ΠΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ stdlib Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ Π²
src/asm_stdlib/stdlib.nasm
.
Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΡΠΎΠ±ΠΈΡΠ°Π΅ΡΡΡ Π² ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» Π΄Π»Ρ Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠΈ Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠΎΠΌ (Π³Π΄Π΅ ΠΎΠ½Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² JIT ΡΠ΅ΠΆΠΈΠΌΠ΅), Π° ΡΠ°ΠΊ ΠΆΠ΅ Π² ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Π΄Π»Ρ ΡΠ΄ΠΎΠ±ΡΡΠ²Π° ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ. ΠΡΠΈ ΡΡΠΎΠΌ Π΄Π»Ρ ΡΡΠ½ΠΎΡΡΠΈ ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ» ΠΎΠ½Π° Π²ΡΠ²Π΅Π΄Π΅Ρ ΡΠΏΡΠ°Π²ΠΎΡΠ½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΈ Π·Π°Π²Π΅ΡΡΠΈΡ ΡΠ²ΠΎΡ ΡΠ°Π±ΠΎΡΡ.
Π‘Π±ΠΎΡΠΊΠ° ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ make, ΠΎΠ΄Π½Π°ΠΊΠΎ ΡΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΠΈ Π²ΡΡΡΠ½ΡΡ:
$ cd src/asm_strlib
$ nasm -f elf64 stdlib.asm # Π‘Π±ΠΎΡΠΊΠ° ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°
$ ld -e stub_entry -s -S stdlib.o -o stdlib.out # Π‘Π±ΠΎΡΠΊΠ° Π±ΠΈΠ½Π°ΡΠ½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°
ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΡΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ ΠΊΠΎΠ΄Π° ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π² Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌΡΠΉ Π±ΠΈΠ½Π°ΡΠ½ΡΠΉ ΡΠ°ΠΉΠ». ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ stdlib.out
, Π°Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ Π΅Π³ΠΎ ELF Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ ΠΊΠΎΠΏΠΈΡΡΠ΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉΡΡ
ΡΠ°ΠΌ ΠΊΠΎΠ΄ Π² Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°ΠΉΠ». ΠΠ΄Π½Π°ΠΊΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΡ Π΄Π»Ρ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΊ ΡΡΠ½ΠΊΡΠΈΡΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΡΠ°ΠΊΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π·Π½Π°ΡΡ ΠΈΡ
ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ, ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΠΊΠΎΡΠΎΡΡΡ
Π½Π΅Π»ΡΠ·Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΏΡΠΎΡΡΡΠΌ ΠΏΡΡΠ΅ΠΌ Π°Π½Π°Π»ΠΈΠ·Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ΡΠ΅Π³ΠΌΠ΅Π½ΡΠΎΠ².
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π² ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅ ΠΌΠ°Π»ΠΎ ΡΡΠ½ΠΊΡΠΈΠΉ ΠΈ ΠΎΠ½ΠΈ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΌΠ΅Π½ΡΡΡΡΡ, Π±ΡΠ»ΠΎ ΠΏΡΠΈΠ½ΡΡΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΠΈΡΠ°ΡΡ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΉ ΠΊΠ°ΠΊ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ.
Π£Π·Π½Π°ΡΡ ΠΈΡ
ΠΌΠΎΠΆΠ½ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠΈΠ»ΠΈΡΡ readelf
, ΠΏΡΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π² Ρ Π΅Π΅ ΠΏΠΎΠΌΠΎΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ:
$ readelf -a stdlib.o
... 48 ΡΡΡΠΎΠΊ ΠΏΡΠΎΠΏΡΡΠ΅Π½ΠΎ ...
Π’Π°Π±Π»ΠΈΡΠ° ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² Β«.symtabΒ» ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ 16 ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ²:
Π§ΠΈΡ: ΠΠ½Π°Ρ Π Π°Π·ΠΌ Π’ΠΈΠΏ Π‘Π²ΡΠ· Vis ΠΠ½Π΄Π΅ΠΊΡ ΠΈΠΌΠ΅Π½ΠΈ
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS stdlib.nasm
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
3: 000000000000004f 0 NOTYPE LOCAL DEFAULT 1 input_asm.L6
4: 0000000000000059 0 NOTYPE LOCAL DEFAULT 1 input_asm.L4
5: 0000000000000081 0 NOTYPE LOCAL DEFAULT 1 input_asm.L19
6: 0000000000000092 0 NOTYPE LOCAL DEFAULT 1 input_asm.L18
7: 00000000000000a6 0 NOTYPE LOCAL DEFAULT 1 input_asm.L16
8: 0000000000000175 0 NOTYPE LOCAL DEFAULT 1 output_asm.L28
9: 00000000000001a6 0 NOTYPE LOCAL DEFAULT 1 output_asm.L27
10: 00000000000001bf 0 NOTYPE LOCAL DEFAULT 1 output_asm.L29
11: 00000000000001e3 0 NOTYPE LOCAL DEFAULT 1 output_asm.L30
12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 input_asm
13: 00000000000000ad 0 NOTYPE GLOBAL DEFAULT 1 output_asm
14: 00000000000001ef 0 NOTYPE GLOBAL DEFAULT 1 exit_asm
15: 00000000000001fb 0 NOTYPE GLOBAL DEFAULT 1 sqrt_asm
ΠΠ°ΠΊ Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· Π²ΡΠ²ΠΎΠ΄Π° ΡΡΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΊΠΎΠ΄ input_asm
Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ Π² ΡΠ°ΠΌΠΎΠΌ Π½Π°ΡΠ°Π»Π΅, output_asm
Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ ΡΠΎ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ 0xAD
ΠΈ ΡΠ°ΠΊ Π΄Π°Π»Π΅Π΅.
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π² ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΌ ΡΠ΅ΠΌΠ΅ΡΡΡΠ΅ Π±ΡΠ» Π½Π°ΠΏΠΈΡΠ°Π½ Π±ΡΠΊΠ΅Π½Π΄ Π΄Π»Ρ ΡΠΌΡΠ»ΡΡΠΎΡΠ° ΡΡΠ΅ΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ° (ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ Π±ΡΠΊΠ΅Π½Π΄Π° ΠΈ ΡΠΌΡΠ»ΡΡΠΎΡΠ°), ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠ°Π²Π½ΠΈΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ Π½Π°ΡΠΈΠ²Π½ΠΎΠ³ΠΎ x64 ΠΊΠΎΠ΄Π° Ρ Π·Π°ΠΏΡΡΠΊΠΎΠΌ Π½Π° ΡΠΌΡΠ»ΡΡΠΎΡΠ΅ ΡΡΠ΅ΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°.
ΠΠ»Ρ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅ΡΠΈΠΌ Π²ΡΠ΅ΠΌΡ ΡΠ°Π±ΠΎΡΡ Π΄Π²ΡΡ
ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ: ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΠΎΠ³ΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ examples/
(ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ: ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅, Π€ΠΈΠ±ΠΎΠ½Π°ΡΡΠΈ).
ΠΠ΅ΡΠΎΠ΄ΠΈΠΊΠ° ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ
ΠΠ»Ρ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΡ Π·Π°ΡΡΠ°ΡΠ΅Π½Π½ΠΎΠ³ΠΎ Π½Π° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΈ ΠΏΠΎΠ²ΡΡΠ΅Π½ΠΈΡ ΡΠΎΡΠ½ΠΎΡΡΠΈ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ 10000 ΡΠ°Π·. ΠΡΠΈ ΡΡΠΎΠΌ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΏΡΡΡ Π·Π°ΠΏΡΡΠΊΠΎΠ², ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΊΠΎΡΠΎΡΡΡ Π² ΠΏΠΎΡΠ»Π΅Π΄ΡΡΠ²ΠΈΠΈ ΡΡΡΠ΅Π΄Π½ΡΡΡΡΡ ΠΈ ΡΡΠΈΡΠ°Π΅ΡΡΡ ΠΏΠΎΠ³ΡΠ΅ΡΠ½ΠΎΡΡΡ.
ΠΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ ΡΡΠ΅Π½Π΄Π΅
OS: Arch Linux (22.05.2023)
Kernel: linux-6.3.1
CPU: Ryzen 7 4800H
CPU Governor: perfomance (max frequency)
ΠΠΈΠΊΠ°ΠΊΠΈΡ
ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ, ΠΊΡΠΎΠΌΠ΅ ΡΠ΅ΡΡΠΈΡΡΠ΅ΠΌΠΎΠΉ ΠΈ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΡ
, Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ Π½Π΅ Π·Π°ΠΏΡΡΠ΅Π½ΠΎ, Π° ΡΠ°ΠΊΠΆΠ΅ ΡΠ΅ΡΡΠΈΡΡΠ΅ΠΌΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ Π²ΡΠ΄Π°Π½ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ (ΡΡΠΎΠ²Π΅Π½Ρ nice Π²ΡΡΡΠ°Π²Π»Π΅Π½ Π² -20).
Π Π΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ:
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° | x64 | stack cpu | Π£ΡΠΊΠΎΡΠ΅Π½ΠΈΠ΅ |
---|---|---|---|
ΠΠ²Π°Π΄ΡΠ°ΡΠ½ΠΎΠ΅ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ | 9.3 Β± 0.2 ms |
50.6 Β± 0.5 ms |
5.44 Β± 0.03 |
Π§ΠΈΡΠ»ΠΎ Π€ΠΈΠ±ΠΎΠ½Π°ΡΡΠΈ | 68.2 Β± 0.7 ms |
403.1 Β± 0.9 ms |
5.910 Β± 0.012 |
ΠΠ°ΠΊ Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· ΡΠ°Π±Π»ΠΈΡΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π°ΡΠΈΠ²Π½ΠΎΠΉ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΡ Π²ΠΌΠ΅ΡΡΠΎ ΡΠΌΡΠ»ΡΡΠΎΡΠ° Π΄Π°Π΅Ρ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΏΡΠΈΡΠΎΡΡ Π² ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ (Π² 5.5 ΡΠ°Π·).