[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)