Author Topic: Converting arithmetic expressions to Assembly  (Read 1707 times)

Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Converting arithmetic expressions to Assembly
« on: February 15, 2018, 07:48:11 PM »
Hey, guys!
New here. I've just made a simple web-app that attempts to convert arithmetic expressions to i486-compatible assembly:
Arithmetic expression to assembly converter
I've tried to test it (using Flat Assembler), and to me it seems like it produces correct results. However, I am not a professional programmer, so I would like to hear from some experts.
« Last Edit: February 15, 2018, 07:49:47 PM by UniverseIsASimulation »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2349
  • Country: us
Re: Converting arithmetic expressions to Assembly
« Reply #1 on: February 15, 2018, 10:37:42 PM »
Hi UniverseIsASimulation,

Welcome to the forum.

Your web-app is impressive (once it wakes up), but attempting to assemble it results in a long string of syntax errors. If it works in Fasm, better stick to Fasm. Nasm syntax and Fasm syntax are quite similar, but not exactly the same. "2f" etc. seem to be a problem...

Best,
Frank


Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #2 on: February 16, 2018, 07:09:01 AM »
The app is just 600 lines of code, almost all in JavaScript.
What's a more portable syntax for "mov [result],2f"? In FASM, that means "Store the 32-bit floating-point value 2.0 on the address that the pointer 'result' points to.".

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2349
  • Country: us
Re: Converting arithmetic expressions to Assembly
« Reply #3 on: February 16, 2018, 07:18:35 PM »
Code: [Select]
mov dword [result],  __float32__(2.0)

I guess. If you're looking for "portable" you're in the wrong church.

Best,
Frank


Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #4 on: February 17, 2018, 01:32:29 PM »
Uf, that doesn't work in FASM.

I'll stick to FASM though. Programs that try to generate assembly which is supposed to be portable usually target GAS (which is available on both PC and MAC, and uses the same syntax for all x86 architectures), but GAS has a very tough syntax, do we agree?

So, it takes 600 lines of JavaScript to convert arithmetic expressions to Assembly. How many lines of code does it take to convert that Assembly to the machine code? Is it even possible to do in JavaScript or would I have to learn another programming language to do that? I am not planning to actually attempt to do that, I am just curious.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2349
  • Country: us
Re: Converting arithmetic expressions to Assembly
« Reply #5 on: February 18, 2018, 03:23:06 AM »
Yeah, Gas has a pretty bad reputation, but Nasm is no prize in this case.

I don't know anything about Javascript.

Best,
Frank


Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #6 on: March 31, 2018, 04:54:05 PM »
Is there some part of programming you would recommend me to learn so that I can start making some money? Nobody is going to pay me for being able to make a web-app that converts arithmetic expressions to i486-compatible assembly. The only programming language I know well enough right now to be able to do that in is JavaScript.

Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #7 on: April 28, 2018, 04:32:01 PM »
OK, I get it. This isn't a good forum for such questions.

Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #8 on: June 27, 2018, 01:09:33 PM »
Anyway, the web-app has been improved in quite a lot of ways since I last posted here. Now it has syntax highlighting and the diagnostic messages have been substantially improved.

Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #9 on: June 28, 2018, 09:32:56 AM »
I'd like to get some feedback. I used to think that web-app can be useful. Or can it be actually?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2349
  • Country: us
Re: Converting arithmetic expressions to Assembly
« Reply #10 on: June 29, 2018, 03:27:05 AM »
I really don't know what to tell you, UniverseIsASimulation. I personally don't have any arithmetic expressions I need converted to assembly language. If I did, I'd probably want to do it myself, "by hand". But that's just me.

Last I looked, the Fasm Forum was a lot more active than this Forum. Have you posted there? Get any feedback? Do you get any traffic on your web-app? I'm impressed that you could do it, but I really have no need of it. Wish I could tell you something more encouraging!

Best,
Frank


Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #11 on: January 05, 2019, 05:57:07 PM »
Anyway, I've improved my compiler using the Duktape framework to be able not only to translate single directives from my own programming language into Assembly, but to also be able to translate entire simple programs stored in files. Here is one of the first programs I've written in the first programming language I've made myself:
Code: [Select]
;Advanced example: implementing the permutation algorithm.
AsmStart
    debug=0
macro pushIntToStack x
{
sub esp,4
fld dword [x]
fistp dword [esp]
}
macro pushPointerToStack x
{
sub esp,4
lea ebx,[x]
mov [esp],ebx
}
macro pushStringToStack x
{
sub esp,4
mov dword [esp],x
}
format PE console
entry start

include 'win32a.inc'

section '.text' code executable
start:
jmp enterNumber$
enterNumber db "Enter a whole number (1 - 1'000'000).",10,0
enterNumber$:
pushStringToStack enterNumber
call [printf]
pushPointerToStack original
jmp floatSign$
floatSign db "%f",0
floatSign$:
pushStringToStack floatSign
call [scanf]
jmp permutationString$
permutationString db "The permutations of its digits are:",10,0
permutationString$:
pushStringToStack permutationString
call [printf]
AsmEnd
numberOfDigits:=0
i:=0
While i<10
countDigits[i]:=0
i:=i+1
EndWhile
While original>0
numberOfDigits:= numberOfDigits + 1
lastDigit:= mod( original , 10 )
countDigits[ lastDigit ]:=countDigits( lastDigit ) + 1
original:= (original - lastDigit) / 10
EndWhile
AsmStart
if debug=1
AsmEnd
i:=0
While i<10
subscript:=4*i
AsmStart
fld dword [subscript]
fistp dword [subscript]
mov ebx,[subscript]
pushIntToStack (countDigits+ebx)
pushStringToStack integerSign
call [printf]
AsmEnd
i:=i+1
EndWhile
AsmStart
pushStringToStack newLineString
call [printf]
AsmEnd
AsmStart
end if
AsmEnd
topOfMyStack:=1
myStack[(numberOfDigits+1)]:=0
While topOfMyStack>0
currentNumberOfDigits:=myStack ( topOfMyStack * ( numberOfDigits + 1 ) )
i:=0
While i<currentNumberOfDigits
currentNumber(i):=myStack ( topOfMyStack * ( numberOfDigits + 1 ) + ( i + 1 ) )
i:=i+1
EndWhile
AsmStart
if debug=1
AsmEnd
i:=0
While i<currentNumberOfDigits
subscript:=i*4
AsmStart
fld dword [subscript]
fistp dword [subscript]
mov ebx,[subscript]
pushIntToStack (currentNumber+ebx)
pushStringToStack integerSign
call [printf]
AsmEnd
i:=i+1
EndWhile
AsmStart
pushStringToStack newLineString
call [printf]
AsmEnd
AsmStart
end if
AsmEnd
topOfMyStack:=topOfMyStack-1
If currentNumberOfDigits=numberOfDigits
i:=0
While i<numberOfDigits
subscript:=i*4
AsmStart
fld dword [subscript]
fistp dword [subscript]
mov ebx,[subscript]
pushIntToStack (currentNumber+ebx)
pushStringToStack integerSign
call [printf]
AsmEnd
i:=i+1
EndWhile
AsmStart
pushStringToStack newLineString
call [printf]
AsmEnd
Else
i:=0
While i<10
counter:=0
j:=0
While j<currentNumberOfDigits
If currentNumber(j)=i
counter:=counter+1
EndIf
j:=j+1
EndWhile
If counter<countDigits(i)
topOfMyStack:=topOfMyStack+1
myStack(topOfMyStack*(numberOfDigits+1)):=currentNumberOfDigits+1
j:=0
While j<currentNumberOfDigits
myStack(topOfMyStack*(numberOfDigits+1)+(j+1)):=currentNumber(j)
j:=j+1
EndWhile
myStack (topOfMyStack * (numberOfDigits + 1) + (j + 1) ) := i
EndIf
i:=i+1
EndWhile
EndIf
EndWhile
AsmStart
invoke system,_pause
invoke exit,0

_pause db "PAUSE",0
integerSign db "%d",0
newLineString db 10,0

section '.rdata' readable writable
original dd ?
result dd ?
lastDigit dd ?
numberOfDigits dd ?
countDigits dd 11 dup(?)
subscript dd ?
myStack dd 1000 dup(?)
topOfMyStack dd ?
counter dd ?
i dd ?
currentNumber dd 11 dup(?)
currentNumberOfDigits dd ?
j dd ?


section '.idata' data readable import
library msvcrt,'msvcrt.dll'
import msvcrt,printf,'printf',system,'system',exit,'exit',scanf,'scanf'
AsmEnd
The source code of the compiler, as well as the instructions on how to compile it and use it, can be downloaded here.
So, what do you think about it? Is it worth continuing developing it?
I am also dreaming about making my own LISP-like language, in which you will able to use both S-expressions and infix-expressions (since S-expressions come handy in array and string-manipulation, and infix-expressions come handy in arithmetic expressions), but I am unlikely to have time to develop it in foreseeable future.

Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #12 on: January 07, 2019, 03:53:45 AM »
The command-line version should produce assembly compatible not just with FlatAssembler, but also with some other assemblers (since it outputs hexadecimal IEEE754 instead of things such as "2f"). Can you confirm that it works?

Offline UniverseIsASimulation

  • Jr. Member
  • *
  • Posts: 10
Re: Converting arithmetic expressions to Assembly
« Reply #13 on: January 08, 2019, 07:52:43 AM »
Here is an example output of the command-line tool:
Code: [Select]
;Generated by Arithmetic Expression Compiler (http://flatassembler.000webhostapp.com/compiler.html) run in Duktape.
;;So, this is my second program in my own programming language.
;Inline assembly begins.
debug=0
format PE console
entry start

include 'win32a.inc'

section '.text' code executable
start:

mov dword [esp],_output1
call [printf]
mov dword [esp+4],n
mov dword [esp],_input1
call [scanf]
;Inline assembly ended.
;fib(0):=0
finit
mov dword [result],0x0 ;0
fld dword [result]
fstp dword [result]
push dword [result]
mov dword [result],0x0 ;0
fld dword [result]
fistp dword [result]
mov ebx,[result]
pop dword [fib+4*ebx]
;fib(1):=1
finit
mov dword [result],0x3F800000 ;1
fld dword [result]
fstp dword [result]
push dword [result]
mov dword [result],0x3F800000 ;1
fld dword [result]
fistp dword [result]
mov ebx,[result]
pop dword [fib+4*ebx]
;i:=2
finit
mov dword [result],0x40000000 ;2
fld dword [result]
fstp dword [result]
push dword [result]
pop dword [i]
;While i<n+1
finit
l379056:
fld dword [n]
mov dword [result],0x3F800000 ;1
fld dword [result]
faddp st1,st0
fld dword [i]
fxch
fcomip st1
fstp dword [result]
jna l884416
fld1
jmp l552240
l884416:
fldz
l552240:
fistp dword [result]
mov eax,[result]
test eax,eax
je l409817
;fib(i):=fib(i-1)+fib(i-2) ;Good idea, QBASIC! Treating Assembly arrays as functions, I would have never thought of that! It's really easy to program.
finit
fld dword [i]
mov dword [result],0x3F800000 ;1
fld dword [result]
fsubp st1,st0
fistp dword [result]
mov ebx,[result]
fld dword [fib+4*ebx] ;In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.
fld dword [i]
mov dword [result],0x40000000 ;2
fld dword [result]
fsubp st1,st0
fistp dword [result]
mov ebx,[result]
fld dword [fib+4*ebx] ;In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.
faddp st1,st0
fstp dword [result]
push dword [result]
fld dword [i]
fistp dword [result]
mov ebx,[result]
pop dword [fib+4*ebx]
;i:=i+1
finit
fld dword [i]
mov dword [result],0x3F800000 ;1
fld dword [result]
faddp st1,st0
fstp dword [result]
push dword [result]
pop dword [i]
;EndWhile
finit
jmp l379056
l409817:
;subscript:=(i-1)*4
finit
fld dword [i]
mov dword [result],0x3F800000 ;1
fld dword [result]
fsubp st1,st0
mov dword [result],0x40800000 ;4
fld dword [result]
fmulp st1,st0
fstp dword [result]
push dword [result]
pop dword [subscript]
;Inline assembly begins.
fld dword [subscript]
fistp dword [subscript]
mov ebx,[subscript]
fld dword [fib+ebx]
fstp qword [esp+4]
mov dword [esp],_output2
call [printf]
mov dword [esp],_pause
call [system]
mov dword [esp],0
call [exit]

_output1 db "Enter n (0-50): ",0
_output2 db "The n-th Fibonacci number is: %f",10,0
_input1 db "%f",0
_pause db "PAUSE",0

section '.rdata' readable writable
result dd ? ;Yes, you need to declare it to be used internally by AEC. Hope you don't mind! :-)
n dd ?
i dd ?
subscript dd ?
fib dd 50 dup(?)

section '.idata' data readable import
library msvcrt,'msvcrt.dll'
import msvcrt,printf,'printf',system,'system',exit,'exit',scanf,'scanf'
;Inline assembly ended.
So, what do you get when you try to assemble it using NASM?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2349
  • Country: us
Re: Converting arithmetic expressions to Assembly
« Reply #14 on: January 08, 2019, 09:23:50 PM »
As you could have tried yourself:


forum.asm:4: error: parser: instruction expected
forum.asm:5: error: parser: instruction expected
forum.asm:6: error: parser: instruction expected
forum.asm:8: error: parser: instruction expected
forum.asm:140: error: comma expected after operand 1
forum.asm:143: error: parser: instruction expected
forum.asm:144: error: parser: instruction expected

Best,
Frank