5 ms·
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" ins
by blueflow 4y ago
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.
- 6581 4y agoIt's an 8086 emulator, not a DOS emulator.
- deleted 4y ago[deleted]
- blueflow 4y agoYou 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 4y agoIt'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 http://www.ctyme.com/intr/rb-0210.htm Long time no see Ralf Brown's Interrupt List...
- nhatcher 4y agoOoops, 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/data_parser/data_parser.lalrpop https://github.com/YJDoc2/8086-Emulator/blob/master/src/lib/...
- rep_lodsb 4y agoLooks 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 4y agoHey, 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 4y ago>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!
- yjdoc2 4y agoHey, 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 4y ago