[HN Gopher] Online 8086 Emulator
       ___________________________________________________________________
        
       Online 8086 Emulator
        
       Author : nhatcher
       Score  : 46 points
       Date   : 2023-04-10 09:20 UTC (13 hours ago)
        
 (HTM) web link (yjdoc2.github.io)
 (TXT) w3m dump (yjdoc2.github.io)
        
       | nsxwolf wrote:
       | How do you write a byte to a memory location? I've tried various
       | idioms to reference a memory address in MOV but it rejects them
       | all.
        
         | yjdoc2 wrote:
         | Hey, one simple example is `mov byte[0], 5` . You need to give
         | relative memory address (wrto DS segment value) in the
         | brackets, and specify whether you want to store a byte or word
         | length value.
         | 
         | This syntax is intentionally verbose, so anyone new to assembly
         | wouldn't mistakenly store word when byte was intended.
         | 
         | You can also check the complete supported syntax here :
         | https://yjdoc2.github.io/8086-emulator-web/help in data
         | transfer, mov section.
         | 
         | Hope this helps!
        
           | nsxwolf wrote:
           | That worked!
        
       | jart wrote:
       | One of the best things from my childhood was writing operating
       | systems in Emu8086 https://youtu.be/flj4PDalKrc I'm glad to see
       | we finally have a web based version! For a moment, I was excited
       | and thought the little ball in the bottom right hand corner was
       | an LLM. Although it looks like it needs more work:
       | 
       | > Greetings.I am here for your questions
       | 
       | what is the les instruction?
       | 
       | > I missed what you said. What was that?
       | 
       | what is mov?
       | 
       | > What was that?
       | 
       | what is 8086?
       | 
       | > I didn't get that. Can you say it again?
        
         | yjdoc2 wrote:
         | Hey, sorry to disappoint you, but that is the least "working"
         | feature of this. :sweat_smile: It was a last-minute addition,
         | not well trained, and should ideally be removed, but still is
         | there.
         | 
         | We would really like to hear your thoughts on how we can
         | improve this in a github issue, and we don't have much idea on
         | LLMs, so there is a lot of room for improvements.
         | 
         | In the meantime, you can check the instructions page which
         | lists the information and syntax/usage for them
         | https://yjdoc2.github.io/8086-emulator-web/help
         | 
         | Hope this helps!
        
       | exuanbo wrote:
       | Good job! It reminds me of the assembler simulator I developed,
       | https://exuanbo.xyz/assembler-simulator/
        
         | yjdoc2 wrote:
         | Hey, thanks! Happy to hear that you think this is interesting.
         | Also, your project is amazing! The design is really beautiful,
         | and the features are really awesome! Thanks a lot for sharing
         | this :)
        
         | nhatcher wrote:
         | Oh that's a thing of beauty. Bookmarked!
        
         | jart wrote:
         | This is some of the slickest web design I've seen in a long
         | time. Have you seen https://github.com/jart/blink this?
        
       | b800h wrote:
       | How is it able to access more than 640KB of memory? Am I
       | misremembering the architecture?
        
         | yjdoc2 wrote:
         | Hey, the 8086 has 20 bit memory bus, so it can theoretically
         | support full 1 MB of memory. However, as much as I know, 8086
         | chips never had complete 1 MB,they had at the most 256/512 KB
         | of memory, and rest address space was used instead as memory
         | mapped IO, or to interface with other chips.
         | 
         | When designing this, we never intended to have support for
         | external chips, so instead we designed this to have the full 1
         | MB of memory.
         | 
         | Hope this helps!
        
         | rep_lodsb wrote:
         | Because segment B800h is also RAM here :)
         | 
         | It's not a PC emulator (or even x86 really, it just interprets
         | the mnemonics you write instead of actual machine code).
        
           | b800h wrote:
           | Ah yes of course! You're allowing access to the whole bus
           | width. Got it!
        
         | mshook wrote:
         | You are, on a 8086 the address width is 20 bits, hence the 1 Mo
         | limit.
         | 
         | https://en.wikipedia.org/wiki/X86_memory_segmentation
        
       | lexicality wrote:
       | While I'm impressed at the actual emulator, it does rather feel
       | like someone turned on literally every animation and special
       | effect their web framework had to offer.
       | 
       | I like a bit of juice with my product but this feels like it's
       | gone through a hydraulic press!
        
         | graypegg wrote:
         | HAH, that's a great way to put it.
         | 
         | For me it was the animated coach marks popping up with such
         | amazingly-contextual information nuggets as:
         | 
         | > Step 1: Write your code in the editor
        
           | yjdoc2 wrote:
           | Hey, yes, the initial tutorial can feel a bit too hand-
           | holding. However, it is only one-time and should not reappear
           | once done.
           | 
           | It is intentionally so basic, as we wanted to make sure that
           | any user, including those who have never written any assembly
           | code before , can get a gist of it at the start.
           | 
           | That said, the ` Step 1: Write your code in the editor `
           | might be a bit overkill :smile:
           | 
           | If you have any suggestions on how we can improve the
           | tutorial so new-comers can find it useful, and at the same
           | time, it is not annoying, we would be very happy to hear it
           | in a github issue.
           | 
           | Thanks!
        
         | yjdoc2 wrote:
         | Hey, Sorry about that! Maybe we should have dialed the reactive
         | stuff down a bit! On a side note, if you'd prefer a no-gui
         | setup, this also as a commandline based emulator
         | github.com/YJDoc2/8086-Emulator/ . (Not that this is any excuse
         | for the we ui)
        
           | peterfirefly wrote:
           | It's impressive -- but it makes me feel seasick. I hope it
           | landed some of you a nice webdev job :)
        
       | blueflow wrote:
       | Infuriatingly differently from the 8086 i used to program for.
       | 
       | I tried to enter a "db CDh, 20h" which is the second-shortest
       | valid DOS program.
       | 
       | - The "DB" instruction does not support multiple operands
       | 
       | - Programs needs to have start labels
       | 
       | - Start label can't point to bytes defined by "DB"
       | 
       | - NOP instruction not recognized
       | 
       | - DB cant be used without a label??
       | 
       | So i changed my mind and tried to write a simple 'ret' one-byte
       | program. Which is a valid way to exit a program in DOS and CP/M.
       | Unrecognized token `` found at 0:3 Expected one of Error : ret is
       | encountered without corresponding call
       | 
       | This is not an error in assembly!
       | 
       | Also the terms. "compiling" is the process that generates
       | assembly from a higher language. "assembling" is the process of
       | turning assembly into machine code.
       | 
       | Whatever this is, this is not for me.
        
         | yjdoc2 wrote:
         | Hey, I can totally understand that this did not work out for
         | you. I am glad nonetheless that you gave it a try anyways, and
         | mentioned the issues you faced, so we can improve on them.
         | Thanks for that!
         | 
         | This was originally made primarily for our own use, so I can
         | definitely understand that the choices we made for this is not
         | everyone's cup of tea.
         | 
         | However, I would just like to reply to the points, in case
         | anyone else is also facing the same things.
         | 
         | - DB indeed doesn't support setting multiple different values,
         | and that is definitely a thing we should change when we update
         | his. Alternatively you can set multiple bytes to a same value
         | using `DB [value,count]`
         | 
         | - Yes, this is intentional. As this emulator is not a "true"
         | 8086 emulator that can just start from any memory address, we
         | need a start label, much similar to how C needs a main
         | function.
         | 
         | - Again, intentional. DB is strictly for data storage, and the
         | whole code is (internally) split into data section (at start)
         | and code section (after data section). Thus you cannot define
         | DB once you start the code section. And as said, start
         | indicates entry point of code, so any DB instruction cannot
         | have start label.
         | 
         | - NOP is not implemented, and is an open issue at the repo.
         | 
         | - DB can be used without a label. for example ``` db [7,5] DW
         | 0x7857 start: mov byte[0], 5
         | 
         | ``` is a valid and compiling code. In case you had any issues
         | using DB without label, feel free to comment here, or open an
         | issue on github.
         | 
         | - Yes, ret cannot be used outside procedures. This is again
         | intentional. As this emulator was aimed at students and
         | newcomers to assembly, we wanted to kind of safeguard from
         | accidentally using ret outside of a procedure context. In real
         | assembly, it will let you use ret anywhere, but this does not.
         | 
         | > Also the terms. "compiling" is the process that generates
         | assembly from a higher language. "assembling" is the process of
         | turning assembly into machine code.
         | 
         | You are very much correct on this one. However, in this
         | particular case I would suggest use of 'compiling' is also
         | correct. As noted, this is an emulator of 8086, and we use an
         | string based IR generated from the input assembly code. (This
         | is not the best choice in hind-sight and there is an open issue
         | for changing this). In that sense, we are indeed "compiling"
         | the assembly code you have given to an executable/runnable
         | representation, which then the emulator (which is basically an
         | interpreter in this case) can run.
         | 
         | That said, I do agree that in general, (not in particular
         | context of this emulator) "compiling" is not suited.
         | 
         | ---
         | 
         | All said, This might not be everyone's choice for emulator, and
         | I am glad that you gave it a try. Thanks!
        
           | rep_lodsb wrote:
           | >Yes, ret cannot be used outside procedures. This is again
           | intentional. As this emulator was aimed at students and
           | newcomers to assembly, we wanted to kind of safeguard from
           | accidentally using ret outside of a procedure context.
           | 
           | This decision seems more likely to teach newcomers the wrong
           | things, like expecting the following code to work:
           | def plus {             ; add two numbers on stack, return
           | result on stack             pop ax             pop bx
           | add ax,bx             push ax             ret         }
           | 
           | To catch errors like this, you might want to implement a
           | "shadow stack" in the interpreter that keeps track of the
           | type of each stack element (number or return address).
           | 
           |  _edit, some more thoughts on how to implement this:_
           | 
           | https://news.ycombinator.com/item?id=35517012
           | 
           |  _/ edit_
           | 
           | But the most essential feature of assembly / machine language
           | is that there is in reality no distinction between characters
           | or numbers and memory addresses, procedures and labels, or
           | between code and data. Even compiler-generated code often has
           | jumps to procedures (tail-call optimization).
           | 
           | Also by not exposing any code addresses, your virtual machine
           | becomes less powerful than C - how would you call a function
           | pointer?
        
         | 6581 wrote:
         | It's an 8086 emulator, not a DOS emulator.
        
           | blueflow wrote:
           | You don't need DOS for any of the things i tried to do above.
           | 
           | Even on a non-DOS 8086 platform, you would get the
           | instructions for it to assemble.
        
             | mshook wrote:
             | It's more like a PC 8086 emulator (or at least it tries to
             | be). I mean the example is a call to the BIOS...
             | 
             | http://www.ctyme.com/intr/rb-0210.htm
             | 
             | Long time no see Ralf Brown's Interrupt List...
        
           | [deleted]
        
         | nhatcher wrote:
         | Ooops, yeah it probably needs some work. I _think_ it is the
         | work of a student and I found it surprisingly beautiful and
         | well done. The actual grammar (which is how I stumbled upon
         | this project) is here:
         | 
         | https://github.com/YJDoc2/8086-Emulator/blob/master/src/lib/...
        
           | peterfirefly wrote:
           | Some typos:                   (segment-register) [bs/bp/si/di
           | , signed word number]; The offset is taken from the
           | registers, and the number is added to it         (segment-
           | register) [bs/bp , si/di , (signed word number) ];
        
             | yjdoc2 wrote:
             | Hey, I'm sorry but can you be more clear in what are the
             | typos? I'd be glad to fix them, but just seem to miss them
             | in this comment :sweat_smile:
        
               | peterfirefly wrote:
               | If your site hadn't been so "advanced", I could just have
               | given you a URL ;)
               | 
               | It's in the "Memory" part of the instructions page.
        
           | rep_lodsb wrote:
           | Looks like it's not emulating x86 at all, just interpreting
           | assembly mnemonics as if they were BASIC.
           | 
           |  _edit_
           | 
           | Here's how to define a 'procedure', which is different from a
           | 'label' and can be called:                   def count_up {
           | INC AX             CALL count_up         }
           | start:             XOR AX,AX             CALL count_up
           | 
           | Now the 'C'ultists are polluting assembly language with their
           | curly braces! Notice that SP doesn't change while it counts
           | up, the call stack exists only inside the interpreter.
           | 
           | I actually had a calculator as a kid that could be programmed
           | in both BASIC and a similar pretend-assembler.
        
             | yjdoc2 wrote:
             | Hey, yes I do like the braces ;}
             | 
             | The decision to differentiate procedures from labels was
             | intentional, and taken due to some restrictions of our IR
             | (which is not the best, issue is open to change that).
             | 
             | Also, the way to define procedure is this way (separate
             | form labels), as I felt that might be a bit more familiar
             | to newcomers to assembly, who are coming from other
             | languages.
             | 
             | Call stack exists inside assembler due to the same reason,
             | as in case someone accidentally bashes their stack , it
             | would still not corrupt the whole code. Maybe we should do
             | a better job at reporting this so users can know they have
             | corrupted the stack, instead of silently ignoring.
             | 
             | The SP should be changing, it is probably a bug. Thanks for
             | reporting, I'll try to take a look at it.
        
               | rep_lodsb wrote:
               | >The SP should be changing, it is probably a bug. Thanks
               | for reporting, I'll try to take a look at it.
               | 
               | Since the code doesn't have an address inside the
               | emulated memory space, it kind of makes sense for there
               | to be a separate return stack. Problem is that you're
               | trying to emulate 8086 and not a Forth machine :)
               | 
               | One solution might be to have 'CALL' decrement SP
               | (perhaps writing some dummy value like 0000 or FFFF to
               | memory), and also remember where SS:SP points now. The
               | interpreter's return stack could store that address,
               | along with the reference to the line of code it should
               | return to.
               | 
               | When executing 'RET', check if the stack pointer is at
               | the same location as it was after the last 'CALL', and
               | halt with an error message if it is different. I suggest
               | you also allow 'JMP' to procedures, or just get rid of
               | the separation entirely and make everything a label. The
               | procedure syntax could still be allowed as an alternative
               | but just declare a normal label.
               | 
               | Another small but impactful bug: REP seems to always
               | perform one more iteration when CX is zero!
        
       | kettellvorokz wrote:
       | Looks awesome, good job.
        
         | yjdoc2 wrote:
         | Thanks! Glad you found it interesting.
        
       | yjdoc2 wrote:
       | Hey, I am one of the creators of this emulator! Thanks nhatcher
       | for posting this, glad to see you found this interesting.
       | 
       | A bit of background on this is : we made this when we were
       | students ourselves, learning about 8086, and couldn't find a
       | decent emulator to do some of our lab work (or at least couldn't
       | find a decent one with nice linux support).
       | 
       | We decided to write this primarily for ourselves, and for anyone
       | who want to have an introduction to writing assembly in a
       | friendly environment. This has mistakes, some decisions that
       | seemed good at that time, but are quite bad in hind-site, and you
       | are welcome to open issues on the respective github repos
       | (github.com/YJDoc2/8086-Emulator for the syntax and emulator
       | stuff, github.com/YJDoc2/8086-Emulator-web for the web ui).
       | 
       | We are now busy with other stuff, so the development is not as
       | active as when we initially made this ; however, we try to update
       | and add features, try to do bug fixes, and welcome contributors
       | as much as we can.
       | 
       | Hope this project makes some newcomer interested in amazing
       | domain of assembly, low level systems and system programming!
        
       ___________________________________________________________________
       (page generated 2023-04-10 23:02 UTC)