|
Post by matthew on Jul 13, 2015 17:32:46 GMT -5
Many years ago a few of us on the forum messed about with FASM. But I've never really used NASM.
|
|
|
Post by Adam on Jul 18, 2015 1:01:35 GMT -5
I browsed around the site for a little bit and it looked pretty interesting. I asked because I have been meddling around with writing a compiler in my free time and I haven' worked with assembly since college (up until recently) and even then it was only for 16 bit dos. I currently have a very limited working model, but since switching from using 32 bit registers to 64 bit ones the other night I have some unresolved issues with boolean expressions between variables and constants. I have this compiling, although the while loop doesn't work I believe because there is an issue comparing the i to the 10 (i believe it lies it the bit representations somewhere in putting the 2 byte variable i into an 8 byte register) and and it says that a<10 is false but... the if statements work! my parser translates it into intel syntax assembly it saves it to a file (shown below), compiles it with nasm, links it with ld. and viola! an executable linux package! I know I still have a very long way to go, but none the less I am quite excited to have made it this far. and hopefully just by adding alternate i/o statements for windows it will compile for windows as well.
dim a = 49, b = 2; dim newline = 10; dim char; dim t; dim i = 1
while (i<10) write(i+48) 'i = i + 1 wend
i = 1 a = 1 write((a<10)+48,newline,newline)
if (a=a) ' will print 0' char = 48 write(char, newline); a = 10+a endif if (a>a) ' will print 1 char = 49; write(char, newline); endif if (a<a) ' will print 2 char = 50 write(char, newline) endif if (a<>a) ' will print 3 char = 51 write(char, newline) endif if (a>=a) ' will print 4 char = 52 write(char, newline) endif if (a<=a) ' will print 5 char = 53 write(char, newline) endif
parser output
global _start section .data global_byte_buffer: DB 0 a: DW 49 b: DW 2 newline: DW 10 char: DW 0 t: DW 0 i: DW 1 section .text _start: L0: mov rax,[i] push rax mov rax,10 pop rbx cmp rax, rbx jg L2 mov rax, 0 jmp L3 L2: mov rax, 1 L3: cmp rax, 0 JE L1 mov rax,[i] push rax mov rax,48 pop rbx add rax,rbx mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall JMP L0 L1: mov rax,1 mov [i], ax mov rax,1 mov [a], ax mov rax,[a] push rax mov rax,10 pop rbx cmp rax, rbx jg L4 mov rax, 0 jmp L5 L4: mov rax, 1 L5: push rax mov rax,48 pop rbx add rax,rbx mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[a] push rax mov rax,[a] pop rbx cmp rax, rbx jne L7 mov rax, 1 jmp L6 L7: mov rax, 0 L6: cmp rax, 0 JE L8 mov rax,48 mov [char], ax mov rax,[char] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,10 push rax mov rax,[a] pop rbx add rax,rbx mov [a], ax L8: mov rax,[a] push rax mov rax,[a] pop rbx cmp rax, rbx jl L9 mov rax, 0 jmp L10 L9: mov rax, 1 L10: cmp rax, 0 JE L11 mov rax,49 mov [char], ax mov rax,[char] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall L11: mov rax,[a] push rax mov rax,[a] pop rbx cmp rax, rbx jg L12 mov rax, 0 jmp L13 L12: mov rax, 1 L13: cmp rax, 0 JE L14 mov rax,50 mov [char], ax mov rax,[char] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall L14: mov rax,[a] push rax mov rax,[a] pop rbx cmp rax, rbx je L16 mov rax, 1 jmp L15 L16: mov rax, 0 L15: cmp rax, 0 JE L17 mov rax,51 mov [char], ax mov rax,[char] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall L17: mov rax,[a] push rax mov rax,[a] pop rbx cmp rax, rbx jle L18 mov rax, 0 jmp L19 L18: mov rax, 1 L19: cmp rax, 0 JE L20 mov rax,52 mov [char], ax mov rax,[char] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall L20: mov rax,[a] push rax mov rax,[a] pop rbx cmp rax, rbx jge L21 mov rax, 0 jmp L22 L21: mov rax, 1 L22: cmp rax, 0 JE L23 mov rax,53 mov [char], ax mov rax,[char] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall mov rax,[newline] mov [global_byte_buffer], al mov rax, 1 mov rdi, 1 mov rsi, global_byte_buffer mov rdx, 1 syscall L23: MOV rax,60 ;send exit command xor rdi, rdi syscall
|
|
|
Post by matthew on Jul 18, 2015 7:11:09 GMT -5
The nearest that I've ever got to doing something like that was looking at the ROM disassembly's for old home computers like the C64 or Sinclair Spectrum and I've read a few books by the author Herbert Schildt who usually includes example code for expression parsing. I seem to remember someone on the forum recommended the Dragon Book for learning about compiler writing but it might be a bit out-of-date now.
|
|
|
Post by Adam on Jul 20, 2015 16:37:02 GMT -5
I found out I was using rax instead of ax and it was causing it to reference illegal memory. also I had my stack pointer math wrong. got that fixed up and now I can compile and run this dim newline = 10 dim i = 0 dim limiter = 10 dim count = 0
sub writeMe(char) write(char) endsub
sub woo(a)
count = count + 1 while (i<limiter) if (i>=5) a = 48+i writeMe(a) '48 = 0 else a = i+65 writeMe(a) '65 = A endif i=i+1 wend i = 0 limiter = limiter/2 writeMe(newline) if (limiter > 1) woo(48) endif endsub
woo(48) write(newline,count+48) And it prints out this compile finished ABCDE56789 ABCDE AB
3
I have heard good things about the dragon book, I am currently reading through the book I mentioned earlier, but after I've finished with this one I will be sure to check it out! now that I have my boolean expressions working and I have function calling with parameters working correctly, my next goal is to get local variables working. I took a break from the compiler because I was going through assembly madness and decided to start working on an ide, it works but it is unstable (because webkit is VERY buggy unfortunately). It uses python with webkit and gtk and can currently create a new file, save, and invokes the compiler but, it doesn't highlight for the right language yet...  
|
|
|
Post by Adam on Jul 21, 2015 19:32:20 GMT -5
sorry for the double post, but I was curious if this project would compile to windows, I have it on GitHub and have set up build targets for windows but I currently don't know how well it works on windows. the compile is able to create programs for windows now but I haven't been able to test to see how well they work (the only real difference are the system interrupts used)
|
|
|
Post by matthew on Jul 22, 2015 13:45:39 GMT -5
I've currently got GCC installed on Windows but I haven't got NASM installed. :-(
But I've got the day off on Friday so I'll try and test it then. ;-)
|
|
|
Post by Adam on Jul 23, 2015 14:42:35 GMT -5
I was up until 3 am last night trying to get the windows specific assembly fleshed out, I have emptyProgram.txt compiling and run on windows 8.1. although I couldn't get test.txt to run. I look forward to hearing how things go for you Matthew  also, as noted in the updated readme, I ended up switching from gcc to GoLink for linking the object file, there is a link to the go link download in the readme. After downloading golink put it in the same directory as the project, and after setting the command line arguments for the codeblocks project the compiler should take care of it for you
|
|
|
Post by matthew on Jul 24, 2015 12:58:12 GMT -5
Okay, well I had to compile from the command-line because I haven't got Code::Blocks installed anymore but the process went fine, just a few warnings but no errors. When I tried the project it built and linked okay but crashed when it tried to run. I've uploaded an image here which shows how everything went.
|
|
|
Post by Adam on Jul 24, 2015 16:16:09 GMT -5
What console is that? a tabbed cmd line in windows is unheard of lol. I think i have narrowed the crash down to the subroutine epilog, if you try compiling anything without subroutines I believe it will work, thanks 
|
|
|
Post by Adam on Jul 24, 2015 19:31:21 GMT -5
Okay, well I had to compile from the command-line because I haven't got Code::Blocks installed anymore but the process went fine, just a few warnings but no errors. When I tried the project it built and linked okay but crashed when it tried to run. I've uploaded an image here which shows how everything went. Since you spent some time with fasm, would you possibly be able to find the issue with my subroutine assembly? in linux it works fine, but I have been able to isolate the issue in windows down to three lines, if you run run it with test.subwithparam the write function in the printr subroutine works then it crashes somewhere with these lines add rsp, 0 pop rbp ret I assume it is the pop statement, but in the beginning of the subroutine there is a call push rbp the exception code is 0x05 which google led me to believe is an memory access violation. but, the asm looks right to me. any ideas?
|
|
|
Post by matthew on Jul 25, 2015 12:56:45 GMT -5
Well I've basically got my Windows machine kitted out like a Linux box. I use Console instead of the command-prompt and I've got nano, GnuWin32 and a lot of other tools installed. Sadly, I really didn't do much with FASM other than convert some OpenGL examples in it. The boiler-plate assembly code had already been written. DJLinux or Tom could probably figure out what was wrong though.
|
|
|
Post by matthew on Jul 25, 2015 13:08:41 GMT -5
Just a quick update test.if, test.while and test.txt.random all work. But as expected test.subWithParam doesn't.
|
|