The new revision handle calls from machine code, written in a module, to scripts of M2000 (modules). Just see the code to understand how this is possible.
Function module() revised and a new keyword AddressOf added.
Η νέα αναθεώρηση μπορεί να καλεί τμήματα της Μ2000 από κώδικα μηχανή που γράφουμε σε ένα τμήμα. Δείτε το κώδικα.
Η τμήμα() αναβαθμίστηκε καθώς και μια νέα η ΔιεύθυνσηΑπό προστέθηκε.
Program with English M2000 keywords. Open m2000.exe and write edit A then copy the code in the module editor and press Esc. Write A and press enter to execute.
Cls
far=if(rnd>.5->false, true)
Print if$(far=true->"Using dec ecx && jnz rel32","Using loop rel8")
clip=false
Print "Use this disassembler:"
Print "https://defuse.ca/online-x86-assembler.htm#disassembly2"
// Print monitor.stack (display size in use of return stack )
// Print monitor.stack.size (the pre-allocate return stack size, >30MByte)
// Version 11 Revision 15
Buffer clear BinaryData as Long*10
Return BinaryData, 1:=500
Buffer code clear alfa as byte*1024
module beta {
print :print "done"
}
module beta2 {
print eval(BinaryData,0),
}
Pc=0
Code_Prolog()
Op(0x51, 0x31, 0xC0) ' push ecx : xor eax, eax
OpLong(0xb9, 100) ' mov ecx, 100
mLoop=pc // need that
op(0x01, 0xc8) ' add eax, ecx (eax=eax+ecx)
OpLong(0xa3, BinaryData(0)) ' mov ds:BinaryData(0), eax ' copy to data section
Op(0x51, 0x50) ' push ecx: push eax
CallModule(AddressOf beta2)
Op(0x58, 0x59) ' pop eax : pop ecx
if far then
op(0x49) ' dec ecx
Loop2(mLoop)
else
Loop(mLoop) // 2 bytes (dec ecx)
end if
CallModule(AddressOf beta)
Op(0x59, 0x31, 0xC0) ' pop ecx : xor eax,eax
Ret()
document doc$
for i=0 to pc-1
doc$=hex$(eval(alfa, i),1)
next
Print "Code:";doc$
if clip then clipboard doc$: exit
Try Ok {
profiler
Execute Code alfa, 0
print timecount
}
M=Uint(Error)
Print eval(BinaryData,0)
Print monitor.stack
End
Sub Op()
while not empty
Return alfa, pc:=number
pc++
end while
End Sub
Sub OpLong()
Return alfa, pc:=number, pc+1:=number as long
pc+=5
End Sub
Sub Code_Prolog()
op(0x58, 0x59, 0x59, 0x59, 0x59, 0x50)
End Sub
Sub Ret()
Return alfa, pc:=0xC3
pc++
End Sub
// module() return the real address of module calling function.
// The AddressOf number passed as parameter to this function
// so we Push the AddressOf modulename1
// and then we call code at address module() (using relative addressing)
Sub CallModule()
Return alfa, pc:=0x68, pc+1:=number as long
pc+=5
Return alfa, pc:=0xE8, pc+1:=module()-pc-5-alfa(0) as long
pc+=5
End Sub
// 0xE2 cb LOOP rel8 D Valid Valid Decrement ECX ; jump short if count ≠ 0.
// 0xE1 cb LOOPE rel8 D Valid Valid Decrement ECX ; jump short if count ≠ 0 and ZF = 1.
// 0xE0 cb LOOPNE rel8 D Valid Valid Decrement ECX ; jump short if count ≠ 0 and ZF = 0.
Sub Loop()
Return alfa, pc:=0xe2, pc+1:=(number-pc-2+256)
pc+=2
End Sub
// 0x49 dec ecx // OF, SF, ZF, AF, and PF flags are set according to the result.
// 0x85 jnz rel32
// by default this (number-pc-5+0xFFFFFFFF) is type of modulo 2^32 (same as binary.add())
Sub Loop2()
Return alfa, pc:=0x0F,pc+1:=0x85, pc+2:=(number-pc-5+0xFFFFFFFF) as long
pc+=6
End Sub
Πρόγραμμα με ελληνικές εντολές. Στη κονσόλα της Μ2000 γράφουμε σ Α και ανοίγει ο διορθωτής προγράμματος για το τμήμα Α. Αντιγράφουμε τον κώδικα από εδώ και πατάμε το Esc. Γράφουμε Α και πατάμε το Enter.
οθόνη
μακρυά=αν(τυχαίος>.5->ψευδές, αληθές)
τύπωσε αν$(μακρυά=αληθές->"Χρήση dec ecx && jnz rel32","Χρήση loop rel8")
κλιπ=ψευδές
τύπωσε "Χρησιμοποίησε αυτό:"
τύπωσε "https://defuse.ca/online-x86-assembler.htm#disassembly2"
// τύπωσε ΕΛΕΓΧΟΣ.ΣΩΡΟΥ // (δίνει το μέγεθος του σωρού επιστροφής του διερμηνευτή σε χρήση)
// τύπωσε ΕΛΕΓΧΟΣ.ΜΕΓΕΘΟΣ.ΣΩΡΟΥ //(το μέγεθος του σωρού επιστροφής, >30MB )
διάρθρωση κενή ΔυαδικάΣτοιχεία ως μακρύς*10
επιστροφή ΔυαδικάΣτοιχεία, 1:=500
διάρθρωση κώδικα Άλφα ως ψηφίο*1024
τμήμα Βήτα {
τύπωσε :τύπωσε "Ολοκληρώθηκε"
}
τμήμα Βήτα2 {
τύπωσε εκφρ(ΔυαδικάΣτοιχεία,0),
}
μετρ_προγρ=0
Πρόλογος_Κώδικα()
Κωδικοί_8μπιτ(0x51, 0x31, 0xC0) ' push ecx : xor eax, eax
Κωδικός_Μακρύς(0xb9, 100) ' mov ecx, 100
σημείο_κλήσης=μετρ_προγρ
Κωδικοί_8μπιτ(0x01, 0xc8) ' add eax, ecx (eax=eax+ecx)
Κωδικός_Μακρύς(0xa3, ΔυαδικάΣτοιχεία(0)) ' mov ds:ΔυαδικάΣτοιχεία(0), eax
Κωδικοί_8μπιτ(0x51, 0x50) ' push ecx: push eax
ΚλήσηΤμήματος(ΔιεύθυνσηΑπό Βήτα2)
Κωδικοί_8μπιτ(0x58, 0x59) ' pop eax : pop ecx
αν μακρυά τότε
Κωδικοί_8μπιτ(0x49) ' dec ecx
Επανάληψη2(σημείο_κλήσης)
αλλιώς
Επανάληψη(σημείο_κλήσης) // 2 bytes (dec ecx)
τέλος αν
ΚλήσηΤμήματος(ΔιεύθυνσηΑπό Βήτα)
Κωδικοί_8μπιτ(0x59, 0x31, 0xC0) ' pop ecx : xor eax,eax
Επιστροφή()
έγγραφο κειμ$
για ι=0 έως μετρ_προγρ-1
κειμ$=δεκαεξ$(εκφρ(Άλφα, ι),1)
επόμενο
τύπωσε "Κώδικας:";κειμ$
αν κλιπ τότε πρόχειρο κειμ$: έξοδος
Δες Καλά {
αναλυτής
εκτέλεση κώδικα Άλφα, 0
τύπωσε φόρτος
}
Μ=δυαδικό.ακέραιο(Λάθος) // επιστρέφει τον eax
τύπωσε εκφρ(ΔυαδικάΣτοιχεία,0)
τύπωσε ΕΛΕΓΧΟΣ.ΣΩΡΟΥ
τέλος
ρουτίνα Κωδικοί_8μπιτ()
ενώ όχι κενό
επιστροφή Άλφα, μετρ_προγρ:=αριθμός
μετρ_προγρ++
τέλος ενώ
τέλος ρουτίνας
ρουτίνα Κωδικός_Μακρύς()
επιστροφή Άλφα, μετρ_προγρ:=αριθμός, μετρ_προγρ+1:=αριθμός ως μακρύς
μετρ_προγρ+=5
τέλος ρουτίνας
ρουτίνα Πρόλογος_Κώδικα()
Κωδικοί_8μπιτ(0x58, 0x59, 0x59, 0x59, 0x59, 0x50)
τέλος ρουτίνας
ρουτίνα Επιστροφή()
επιστροφή Άλφα, μετρ_προγρ:=0xC3
μετρ_προγρ++
τέλος ρουτίνας
ρουτίνα ΚλήσηΤμήματος()
επιστροφή Άλφα, μετρ_προγρ:=0x68, μετρ_προγρ+1:=αριθμός ως μακρύς
μετρ_προγρ+=5
επιστροφή Άλφα, μετρ_προγρ:=0xE8, μετρ_προγρ+1:=τμήμα()-μετρ_προγρ-5-Άλφα(0) ως μακρύς
μετρ_προγρ+=5
τέλος ρουτίνας
// 0xE2 cb LOOP rel8 D Valid Valid Decrement ECX ; jump short αν count ≠ 0.
ρουτίνα Επανάληψη()
επιστροφή Άλφα, μετρ_προγρ:=0xe2, μετρ_προγρ+1:=(αριθμός-μετρ_προγρ-2+256)
μετρ_προγρ+=2
τέλος ρουτίνας
// 0x49 dec ecx // OF, SF, ZF, AF, and PF flags are set according έως the result.
// 0x85 jnz rel32
// by default this (αριθμός-μετρ_προγρ-5+0xFFFFFFFF) is type of modulo 2^32 (same as binary.add())
ρουτίνα Επανάληψη2()
επιστροφή Άλφα, μετρ_προγρ:=0x0F, μετρ_προγρ+1:=0x85, μετρ_προγρ+2:= (αριθμός-μετρ_προγρ-5+0xFFFFFFFF) ως μακρύς
μετρ_προγρ+=6
τέλος ρουτίνας
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.