Τρίτη, 20 Φεβρουαρίου 2018

Αναθεώρηση 48 Έκδοση 9.0- Εκτέλεση Γλώσσας Μηχανής

Σε αυτήν την αναθεώρηση έφτιαξα την εντολή Εκτέλεση Κώδικα να εκτελεί κώδικα σε γλώσσα μηχανής που γράφουμε σε διάρθρωση μνήμης για εκτελέσιμο κώδικα με την Διάρθρωση Κώδικα. Σε αυτή τη διάρθρωση ο κώδικας τρέχει χωρίς να μπορεί να γράψει σε αυτήν. Για να γράψει αποτελέσματα φτιάχνουμε μια άλλη διάρθρωση. Επιπλέον αν η εκτέλεση επιστρέψη μη μηδενική τιμή τότε βγαίνει λάθος, το οποίο μπορούμε να διαβάσουμε ως αριθμό και αυτό μπορεί να είναι ένα αποτέλεσμα.
Παρακάτω είναι ένα πρόγραμμα με Ελληνικές εντολές και ακολουθεί σε το ίδιο με Αγγλικές εντολές (η Μ2000 έχει δυο λεξικά αναγνωριστικών, Ελληνικό και Αγγλικό).


Δουλεύει και σε Ubuntu με Wine.

\\ Φτιάχνουμε μια διάρθρωση μνήμης για δεδομένα
Διάρθρωση Δεδομένα ως Μακρύς*10
Επιστροφή Δεδομένα, 1:=500
Διάρθρωση Κώδικα Εκτελέσιμη ως ψηφίο*1024
\\ δες εδώ https://defuse.ca/online-x86-assembler.htm
\\ μετατρέπει την Assembly σε γλώσσα μηχανής
Διεύθυνση=0
\\ x86 Γλώσσα Μηχανής
\\ Το Δεδομένα(0) γυρνάει την διεύθυνση του πρώτου μακρύ (Long)
\\ Το Δεδομένα(1) γυρνάει την διεύθυνση του δεύτερου μακρύ
ΚωδΜακρύς(0xb8, 5100) ' mov eax, 5100     ' 5100 στο eax
ΚωδΨηφΨηφ(0x83, 0xC0 ,5) ' add  eax,0x5   ' πρόσθεσε 5 στο eax
ΚωδΨηφΜακρύς(0x3,0x5, Δεδομένα(1)) ' add eax, [Δεδομένα(1)]  ' πρόσθεσε στο eax το 500 από το δεύτερο μακρύ στο Δεδομένα
ΚωδΜακρύς(0xa3, Δεδομένα(0)) ' mov [Δεδομένα(0)], eax
Σημ : ΚωδΨηφ(0x31, 0xC0) ' xor eax, eax 'σημαίνει eax=0  ' χωρίς αυτό θα πάρουμε το  5605 στο Μ
Επιστροφή() ' Επιστροφή
\\ Τέλος Κώδικα
Δες οκ {
      Εκτέλεση Κώδικα Εκτελέσιμη, 0
}
Μ=Δυαδικό.Ακέραιο(Λάθος)
Δεκαεξ Μ
Τύπωσε Μ
Τύπωσε Λάθος, οκ
Τύπωσε Εκφρ(Δεδομένα, 0) ' 5605

Ρουτίνα Επιστροφή()
      Επιστροφή Εκτελέσιμη, Διεύθυνση:=0xC3
      Διεύθυνση++
Τέλος Ρουτίνας
Ρουτίνα ΚωδΨηφΨηφ()
      Επιστροφή Εκτελέσιμη, Διεύθυνση:=Αριθμός, Διεύθυνση+1:=Αριθμός, Διεύθυνση+2:=Αριθμός
      Διεύθυνση+=3
Τέλος Ρουτίνας
Ρουτίνα ΚωδΨηφ()
      Επιστροφή Εκτελέσιμη, Διεύθυνση:=Αριθμός, Διεύθυνση+1:=Αριθμός
      Διεύθυνση+=2
Τέλος Ρουτίνας
Ρουτίνα ΚωδΜακρύς()
      Επιστροφή Εκτελέσιμη, Διεύθυνση:=Αριθμός, Διεύθυνση+1:=Αριθμός ως Μακρύς
      Διεύθυνση+=5
Τέλος Ρουτίνας
Ρουτίνα ΚωδΨηφΜακρύς()
      Επιστροφή Εκτελέσιμη, Διεύθυνση:=Αριθμός, Διεύθυνση+1:=Αριθμός, Διεύθυνση+2:=Αριθμός ως Μακρύς
      Διεύθυνση+=6
Τέλος Ρουτίνας


Και το ίδιο με αγγλικές εντολές:

\\ we make a buffer to use for DATA
Buffer BinaryData as Long*10
Return BinaryData, 1:=500
Buffer code alfa as byte*1024
\\ use https://defuse.ca/online-x86-assembler.htm
\\ to find opcodes
Pc=0
\\ x86 Machine Code
OpLong(0xb8, 5100) ' mov eax, 5100    ' 5100 to eax
OpByteByte(0x83, 0xC0 ,5) ' add  eax,0x5   ' add 5 to eax
OpByteLong(0x3,0x5, BinaryData(1)) 'add eax, [BinaryData(1)]  ' add eax 500 from second long on BinaryData
OpLong(0xa3, BinaryData(0)) ' mov [BinaryData(0)], eax
rem : OpByte(0x31, 0xC0) ' now eax=0  ' without this we get 5605 in M
Ret() ' return
\\ end of code
Try Ok {
      Execute Code alfa, 0
}
M=Uint(Error)
Hex M
Print M
Print Error, ok
Print Eval(BinaryData, 0) ' 5605

Sub Ret()
      Return alfa, pc:=0xC3
      pc++
End Sub
Sub OpByteByte()
      Return alfa, pc:=number, pc+1:=number, pc+2:=number
      pc+=3
End Sub
Sub OpByte()
      Return alfa, pc:=number, pc+1:=number
      pc+=2
End Sub
Sub OpLong()
      Return alfa, pc:=number, pc+1:=number as long
      pc+=5
End Sub
Sub OpByteLong()
      Return alfa, pc:=number, pc+1:=number, pc+2:=number as Long
      pc+=6
End Sub