Hi, I have made a program in "Visual Basic"(VB Called) ML.

ML stands for math language.
I made it cause I needed to make alot math rutines, and just to make something like:

***

B = 4
C = B * 4
A = B * 3 + C

***

would take 15 min or more.(For me.)
That would proberbly mean 4 hours constant work for me, just for these rutines and what about the future?

So I have developed a program called ML(Math Language).
ML can take something like:

***

B = 4
C = B * 4
A = B * 3 + C

***

and convert it to assembly in less then a second.

The program includes a reference to using the Math Language.

If you want to create a byte contaning 4 bytes just do something like:

***

MyByte as (4)bytes

***


If you want to set the value of it then use something like:

***

MyByte = 100

***

I would say pretty simple.

Note that it only support 1, 2, 4, 6, 8, 10 byte types. Though if you try with a 3 byte type then it would be converted to 4.

But there might be some errors, assembly errors, incorrect use of the registers, performance errors, or just not easy to use as language.

If you've found a error please report it on this thread or on my email:http://www.asmcommunity.net/board/cryptmail.php?tauntspiders=in.your.face@nomail.for.you&id=6234bc812276459eb27b9c3de33dbccc
I have compiled it on a Win2000 so it may not work for some OS.

Imediate reporting of errors is very much appreciated.

The zip file only contains a exe file.

I might post the dll files, if needed, cause there is no need to waste space.

JulianS
Posted on 2003-09-12 11:49:05 by JulianS
I went to test it with the following:


A as 4bytes
B as 4bytes

A = A * 4
B = A * 9 + B


Your program produced the following code:


LEA AX, A
MUL 4
LEA 4, DX:AX
MOV A, 4
LEA AX, A
MUL 9
LEA 9, DX:AX
ADD B, 9

I must say the output is definitely wrong. Firstly A is defined as 4bytes (dword) and thus the whole value cannot fit into ax. Secondly you cannot mul immediate. You cannot lea immediate, DX:AX.

Anyway I think your code should output


mov eax, A
shl eax, 2
mov A, eax ;<- Not really needed, but what the hell
mov ecx, B
lea ecx, [eax*8+ecx]
add ecx, eax
mov B, ecx

Sometimes muiltplications could be easily replaced by shifts and divides by shifts provided they are power of 2.

Anyway I wish you all the best.
Posted on 2003-09-12 12:28:01 by roticv
Okay I just realised that I made a mistake (did not really read the yellow box). Since immediates are not allowed, I changed the code to:


A as 4bytes
B as 4bytes
C as 4bytes

A = B / C
A = A * B
B = A * A + B
C = B / A

Your program output the following:


MOV A, B
LEA AX, A
MUL B
LEA B, DX:AX
MOV A, B
LEA AX, A
MUL A
LEA A, DX:AX
ADD B, A

MOV C, B

That means your documentation lied. dividision still not supported :grin:
Like I said just now, most of it applied. Anyway you should not be using lea AX, A but mov eax, A

Okay, my hand convertion would be


mov eax, B
mov ecx, C
cdq
div ecx
mov A, eax ;not really needed, but what the hell
mov ecx, B
mul ecx
mov ebx, eax ; not that I wanted to use ebx
mul ebx
add eax, ecx
mov B, eax ;not really needed, but what the hell
xchg eax, ecx
div ecx
mov A, ecx
Posted on 2003-09-12 12:41:21 by roticv
Hi, you made a mistake you should use "()" when making bytes.

You said you tried:

***

A as 4bytes
B as 4bytes
C as 4bytes

A = B / C
A = A * B
B = A * A + B
C = B / A

***

Thats wrong it should be:

***

A as (4)bytes
B as (4)bytes
C as (4)bytes

A = B / C
A = A * B
B = A * A + B
C = B / A

***

Now that would have produced:

***

LOCAL A :DWORD
LOCAL B :DWORD
LOCAL C :DWORD

MOV A, B
MOV EAX, B
MUL A
LEA A, EDX:EAX
MOV EAX, A
MUL B
LEA B, EDX:EAX
MOV A, B
MOV EAX, A
MUL A
LEA A, EDX:EAX
MOV EAX, A
MUL A
LEA A, EDX:EAX
ADD B, A

MOV C, B

***

But you're right, something is wrong when dividing.
Anyway it would have used "mov" instead of "lea" if used the "()".


Anyway I will try correction that error and then I will release a new version very soon.

Julian.
Posted on 2003-09-12 14:33:45 by JulianS
Here is an updated version.
It supports division.
When you write:

***

A as (4)bytes
B as (4)bytes
C as (4)bytes

A = B / C
A = A * B
B = A * A + B
C = B / A


***

It makes:

***


LOCAL A :DWORD
LOCAL B :DWORD
LOCAL C :DWORD

MOV EAX, C
DIV B
LEA B, EDX:EAX
MOV EAX, B
DIV C
LEA C, EDX:EAX
MOV A, C
MOV EAX, B
MUL A
LEA A, EDX:EAX
MOV EAX, A
MUL B
LEA B, EDX:EAX
MOV A, B
MOV EAX, A
MUL A
LEA A, EDX:EAX
MOV EAX, A
MUL A
LEA A, EDX:EAX
ADD B, A

MOV EAX, A
DIV B
LEA B, EDX:EAX
MOV EAX, B
DIV A
LEA A, EDX:EAX
MOV C, A

***

Ohh and you said something about "shl" what does that do?
Is it something I need to know?

Thank roticv, your help is appreciated.
Posted on 2003-09-12 14:45:09 by JulianS
Hi, JulianS. This is a very good work you are doing here :alright:
BTW, "shl" is one of the shift instructions, basically whan they do is multiply and divide by powers of 2 by simply "shifing" bits left and right (similar to adding zeroes to the right of a decimal number to simulate a multiply by a power of 10). Masm comes with an opcode reference, so you might want to read about this instructions:
shl
shr
sal
sar
rol
ror
rcl
rcr
...and I hope I'm not fogetting any.
Posted on 2003-09-12 17:18:10 by QvasiModo
sar = shr

Okay,
1) LEA A, EDX:EAX is wrong since there is no such opcodes.
2) MOV C, A is wrong too since there is no such opcodes.
3) edx is not cleared when doing divison (ie cdq or xor edx, edx)
4) My hand conversion is still smaller and shorter. :grin:
5) Maybe your code should use more registers, since using registers rather than memory produce shorter opcodes (save more space.)
Posted on 2003-09-12 23:27:40 by roticv
1. I have read in the help files that every time you divide the results will be in more bytes then the bytes you div?ded. So I have to use "LEA" for data conversion.
If that is wrong that please tell what I should use: "LEA" or "MOV" or "Other".
But I had doubt about using "EDX:EAX". Is using "EDX:EAX" right?

2. "MOV" is a correct opcode from what I know. If you think that there's a better opcode then please tell what it is called and how to use it.

3. Ups. I will clear edx when using it. But do I need to return it's old value back to it when it's done with calculating?

4. Let's see how the program develops, cause I am sure I am gonna work on it another week or more.

5. Well that's the hole point of this code. To save people from using math opcodes. And maybe also from using bytes. Anyway if you have an idea of how to use more opcodes then I will appreciate it if you tell me.

Anyway as soon as you have answered these questions roticv I will have more to work with and I'll start making a new update.
Posted on 2003-09-13 03:37:38 by JulianS
Maybe you can have an option on what registers that could be corrupted (ie used but not preserved). Just a suggestion

1. Actually for multiplication, the results are in EDX:EAX. However since A, B and C are declared as dword, I do no see the point of storing the upper 32bit of the result. So simply store the value in eax.

2. Technically you cannot move memory to memory in one opcode, but there are work arounds for it. The first method is to use stack. ie push A pop B or using a register such as mov eax, A mov B, eax

3. It depends sometiem the value of edx can be destroyed. For the rule of the C compiler. Windows api follows this logic too since it is coded in C if I am not wrong. Preserve ebx, edi, esi if you use them, edx, eax, ecx could be destroyed.

4. Sometimes it is hard to code a program that can code better than a guru. Okay, firstly I doubt you would use xchg in your program, but of course it was because I did not want to rely too much on memory. Sometimes, there is no need for local variables because the registers take care of it.

5. For maths the following opcode could be use:
lea ;very good for multiplications and addition and subtration and combintion of them
div/idiv
mul/imul
shr
shl/sar
and ; for % if the value is 2^x-1
add
sub
adc
sbb

Maybe for some optimisations:
xchg

Some notes, you can use shifts with cl. Maybe you can try adding some support for constant instead of pure variables. Sorry but I have yet to test out your other data type. But I doubt they would be used much, since the cpu is 32bit. Maybe you can try adding some support for brackets.
Posted on 2003-09-13 04:00:15 by roticv
Okay I went to test with 2byte. Here's my code


A as (4)byte
B as (2)byte
C as (4)byte

A = B
A = A - C * A

Generated masm code


MOV A, B
SUB C, A
LEA AX, C
MUL A
LEA A, DX:AX

1. Okay the part abt opcode memory,memory does not exist still apply. There is no opcodes with 2 modrm. The most is just one modrm. So there is no such thing as mov A, B and sub C, A.

2. B is 2byte ie a word variable. You cannot just mov eax, B mov A, eax but you need movzx eax, B mov A, eax

3. What I mentioned earlier still applies.

Anyway your program seem to look more like a compiler to me. Good luck to the creation of your compiler.
Posted on 2003-09-13 04:08:03 by roticv
This time you remember to use "()" but you forgot to say "bytes" instead of "byte".

Here is the real code you should have used:

***

A as (4)bytes
B as (2)bytes
C as (4)bytes

A = B
A = A - C * A


***

Now that would make:

***


LOCAL A :DWORD
LOCAL B :WORD
LOCAL C :DWORD

LEA A, B
SUB C, A
MOV EAX, A
MUL C
LEA C, EDX:EAX
MOV EAX, C
MUL A
LEA A, EDX:EAX

***

So instead of using "MOVZX" I used "LEA".
Is that wrong?:confused:

About SUB?

Well here's a quote from the opcodes help file:

***

SUB - Subtract
Usage: SUB dest,src
Modifies flags: AF CF OF PF SF ZF
The source is subtracted from the destination and the result is
stored in the destination.

***

According to this quote you have a destination and a source. The source is subtracted from the destination and stored in the destination.

Very simple.

Julian
Posted on 2003-09-13 04:28:24 by JulianS
Let me quote another source


SUB ? Integer Subtraction
2C ib SUB AL,imm8 Subtract imm8 from AL
2D iw SUB AX,imm16 Subtract imm16 from AX
2D id SUB EAX,imm32 Subtract imm32 from EAX
80 /5 ib SUB r/m8,imm8 Subtract imm8 from r/m8
81 /5 iw SUB r/m16,imm16 Subtract imm16 from r/m16
81 /5 id SUB r/m32,imm32 Subtract imm32 from r/m32
83 /5 ib SUB r/m16,imm8 Subtract sign-extended imm8 from r/m16
83 /5 ib SUB r/m32,imm8 Subtract sign-extended imm8 from r/m32
28 /r SUB r/m8,r8 Subtract r8 from r/m8
29 /r SUB r/m16,r16 Subtract r16 from r/m16
29 /r SUB r/m32,r32 Subtract r32 from r/m32
2A /r SUB r8,r/m8 Subtract r/m8 from r8
2B /r SUB r16,r/m16 Subtract r/m16 from r16
2B /r SUB r32,r/m32 Subtract r/m32 from r32

You might wonder what is r/m32. Okay r/m32 is modrm. It is in the form of xx:xxx:xxx. The first 2upperbits tells the cpu how to treat what is in the lower 3bit. (ie to view it as a pointer or a register) So in short for any opcode that makes use of a full modrm, one *must* be a register, and the other can be a register or a pointer. So like I did mention so many times, there is no such opcodes that have both its destination and source as memory.

lea is different from mov. Firstly it loads the address of the pointer (What is within the brackets) into the register. Technically your lea is used wrongly because the destination *must* be a register for lea. Seriously try compiling the output.

PS. Did you ever tried compiling the output? There will be alot of errors.
Posted on 2003-09-13 07:20:29 by roticv

Did you ever tried compiling the output? There will be alot of errors.

He's right. You should also try compiling his manual conversions and run them with a debugger, to see how they work step by step. This helps a lot understanding what's really going on, what values are in the registers at different places in the code, etc. Compare with the output your program is generating and you'll quickly see the differences.
Posted on 2003-09-13 11:17:48 by QvasiModo
Sorry but I don't have a debugger.
I only have masm32.
Do you know any debugger?
If so then please tell where to download it.

Anyway I will release a new version tommorow.
In that version I hope most errors has been solved.


Julian
Posted on 2003-09-13 12:18:50 by JulianS
Quite interesting program you've got there JulianS. Thanks for sharing it :)

OllyDbg is a free debugger:
http://home.t-online.de/home/Ollydbg/
Posted on 2003-09-13 12:34:53 by Delight
Hi, new update. But sorry for being one day to late. (Connection problems etc......)

Anyway the exe file has a new function.
A function that you can define your self.
The function let's you select the upcode that you want to convert bettwen data types with.
Anyway, from start it uses: "MOVSD Des, Dat" do you have any suggestions to what it should use from start?
Posted on 2003-09-15 12:41:47 by JulianS
Interesting start.

I will be very interested when it can handle the full BEDMAS ordering for an expression. If it helps i wrote a parser using a binary tree to do something similar.

http://www.asmcommunity.net/board/index.php?topic=11026&perpage=15&highlight=Parser&pagenumber=1

Regards,
:NaN:
Posted on 2003-09-15 16:50:01 by NaN
Hey NaN,

I do think your program is very interseting. I think it is possible for you to add some support for basic algebra. Maybe it could even be grown into one that can help me differeniate/intergrate :grin: I will try to take a look into it when I have the time. For now, time is pretty short for me. :)

Regards,
Victor
Posted on 2003-09-17 08:38:42 by roticv
Victor what do you belive should be in the white box in ML?
You don't have to hurry but getting an answer before the day after tommorow would be nice.
Thanks.

Julian
Posted on 2003-09-17 09:41:37 by JulianS
Is movsd used as a macro? If I remmeber correctly movsd is for stringopcodes, so perhaps change it to movd and define the marco movd as


movd MACRO Var1, Var2
push Var2
pop Var1
ENDM

Okay when I use


A as (4)bytes
B as (2)bytes
C as (4)bytes
D as (2)bytes

A = B
A = C * D - A / B
D = A

I get an intersting error. Yippy I crashed VB.. hahaha



---------------------------
ML
---------------------------
Run-time error '13':

Type mismatch
---------------------------
OK
---------------------------

However looking at the generated code, there are still many errors. I would suggest that you remove support for byte and words, as it would make your job much easier. Also very seldom people use byte or word nowadays. (Remember that we are now using a 32-bit cpu :) )
Okay VB crashing is getting irritating. The next test code I put together failed badly.


A as (4)bytes
B as (4)bytes
C as (4)bytes

A = B
A = C - A
B = C / A
C = B + A

If I remove the declaration, it just work fine. mhmm that's weird I must say. Now let me touch on the generated output


MOV A, B
SUB A, C

MOVSD AX, C

DIV A
MOVSD DX:AX, A

MOV B, A
ADD A, B
MOV C, A

1) For A = B the generated code is mov A, B which is wrong. Perhaps you add the marco above and output it as movd A, B
2) For A = C - A, the generated code is sub C, A which is wrong. You need to add mov eax, A then sub C, eax. Perhaps you can use some marcos too (again.. hehe...). I have created one for you.
subd MACRO Var1, Var2

mov eax, Var2
sub Var1, eax
ENDM

Use it like subd C, A

One more thing, you need to check where it is stored. For example if the input is A = C - B You need to change it by adding (the most crude code I could think of)


movd A, C
subd C, B

Or perhaps you can create yet another marco. But now I am too lazy to code one more :tongue:
3) Now for B = C / A. The output code is wrong I must say. Ah I some butched code


mov eax, C
cdq
div A
mov B, eax

Maybe you can also derive a marco for it. haha
4) For C = B + A, you can do what I said for sub. Perhaps even coding another marco. Just make sure you do not produce code like movd C, C or something like that.

Since I missed testing out multiplication, I code more test code.
A = B * C

Generated code:


MOVSD AX, B

MUL C
MOVSD DX:AX, C

MOV A, C

Ah it is wrong. Perhaps you can change the output such that it looks like the following:


mov eax, B
imul eax, C
mov A, eax

Or something like that.

I am tired, but I think it is better that you work on the basic operations first. The more advance stuffs will have to come later as you need do what NaNdid, create a good parser. Creating a good parser is hard work imo. Okay I think I should stop here. Long post indeed. :)

Regards,
Victor
Posted on 2003-09-17 11:05:40 by roticv