EMU8086 Solutions
EMU8086 Solutions
EMU8086 Solutions
EMU8086 Solutions
To make sure you are using the latest version, choose check for an update from the help menu.
Windows Vista and Windows 7 users should enable Windows XP compatibly mode. Windows XP compatibly mode should also be applied to all
virtual hardware devices. To further minimize incompatibly problems, it's recommended to run both the emulator and any virtual devices as
system administrator.
(these files are used to communicate with virtual devices and for emulating hardware interrupts )
To step forward press F8 key, to run forward press F9 or press and hold F8. To step backward press F6 key, to run backward press and
hold F6. The maximum number of steps-back can be set in emu8086.ini. For example:
or
Question:
org 100 h
mov si, 0
mov ax, myArray[ si]
ret
Solution:
org 100 h
jmp code
ret
For the computer all bytes look the same, it cannot determine if it's an instruction or a variable. Here is an example of MOV AL, 5
instruction that can be coded with simple variable declarations:
org 100 h
byte1 db 176
byte2 db 5
ret
When you run this program in emulator you can see that bytes 176 and 5 are actually assembled into:
MOV AL, 5
This is very typical for Von Neumann Architecture to keep data and instructions in the same memory, It's even possible to write complete
program by using only DB (define byte) directive.
org 100 h
db 235 ; jump...
db 6 ; 6 - six bytes forward (need to skip characters)
db 72 ; ascii code of ' H'
db 101 ; ascii code of 'e'
db 108 ; ascii code of 'l'
db 108 ; ascii code of 'l'
db 111 ; ascii code of 'o'
db 36 ; ascii code of ' $' - DOS function prints untill dollar.
db 186 ; mov DX, . ... - DX is word = two bytes
db 2 ; 02 - little end
db 1 ; 01 - big end
db 180 ; mov AH, ....
db 9 ; 09
db 205 ; int ...
db 33 ; 21h - 33 is 21h (hexadecimal)
db 195 ; ret - stop the program .
8086 and all other Intel's microprocessors store the least significant byte at a lower address. 102 h is the address of 'H' character = org
100h + 2 bytes (jmp instruction). The above assembly code produces identical machine code to this little program:
org 100 h
jmp code
msg db 'Hello$'
ret
If you open the produced ".com" file in any hex editor you can see hexadecimal values, every byte takes two hexadecimal digits, for example
235 = EB, etc... memory window of the emulator shows both hexadecimal and decimal values.
Problem:
Solution:
The latest version of the emulator uses Terminal font by default and it is MSDOS /ASCII compatible.It is also possible to set the screen font to
Fixedsys from the options . For other controls the font can be changed from c:\emu8086 \emu8086 .ini configuration file. It is well known
that on some localized versions of Windows XP the Terminal font may be shown significantly smaller than in original English version. The latest
version automatically changes default font to 12 unless it is set in emu8086 .ini: FIX_SMALL_FONTS= false. The Fixedsys font is reported
to be shown equally on all systems. It is reported that for small Terminal font D and 0 (zero ) look very alike.
Starting from version 4.00 -Beta-8 the integrated assembler of emu8086 can be used from command line. The switch is /a followed by a full
path to assembly source code files. The assembler will assemble all files that are in source folder into MyBuild directory.
For example:
Note: any existing files in c:\emu 8086\MyBuild\ subdirectory are to be overwritten. The assembler does not print out the status and error
messages to console, instead it prints out everything to this file:
c:\emu8086 \MyBuild\_emu8086 _log.txt
Do not run several instances of the assembler under the same path until <END> appears in the file. You may see if emu8086 is running by
pressing the Ctrl+Alt+Del combination , or by just opening and reopening _emu8086 _log.txt file in Notepad to see if the file is written
completely. This can be checked automatically by another program (the file must be opened in shared mode).
The assembler does not save files with extensions .com, .exe, or .bin, instead it uses these extensions: .com_, .exe_, or .bin _ (there is
underline in the end ). If you'd like to run the file for real just rename .com_ to .com etc.
Theoretically it's possible to make a high level compiler that will use emu 8086 as an assembler to generate the byte code. Maybe even C or
C++ compiler. The example of a basic compiler program written in pure 8086 code may be available in the future .
To disable little status window in the lower right corner, set SILENT_ASSEMBLER= true in emu8086.ini
For the emulator physical drive A: is this file c:\emu8086 \FLOPPY_0 (for BIOS interrupts : INT 13 h and boot).
For DOS interrupts (INT 21h) drive A: is emulated in this subdirectory: c:\emu8086 \vdrive\ a\
Question:
Solution:
There are two general solutions to this task, small and big.
; it is a much shorter solution, because procedures are hidden inside the include file.
ORG 100 h
MOV AX, 27
MOV BX, 77
ADD AX , BX
CALL PRINT_NUM
ret
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_ UNS
end
Question:
jmp start:
array db 17,15,31,16,1 ,123, 71
start:
MOV AX, array_ byte_size
$ is the location counter, it is used by the assembler to calculate locations of labels and variables .
note: this solution may not work in older versions of emu8086 integrated assembler, you can download an update here. the result is always
in bytes. If you declare an array of words you need to divide the result by two , for example:
jmp start:
array dw 12,23,31,15, 19,431 ,17
start:
MOV AX, array_ byte_size / 2
Question:
Solution:
Without far prefix the microprocessor sets a word value (2 bytes) that is pointed by es:[BX] to IP register; with far prefix microprocessor
sets the word value that is pointed by es:[BX] to IP register, and the word at es:[BX+2] is set to CS register.
Question:
Is there another way to achieve the same result without using DD variables?
Solution:
DD definitions and far jumps are supported in the latest version, for example:
addr dd 1235:5124h
If you are using earlier version of emu8086 you can use a workaround, because double words are really two 16 bit words, and words are
really two bytes or 8 bits, it's possible to code without using any other variables but bytes. In other words, you can define two DW values to
make a DD.
For example:
ddvar dw 0
dw 0
Long jumps are supported in the latest version (call far). For previous versions of emu8086 there is another workaround:
jmp 1234h:4567h
EA 67 45 34 12
Therefore, you can define in your code something similar to this code:
The above code is assembled into the same machine code, but allows you to modify the jump values easily and even replace them if
required, for exampe:
when executed the above instruction modifies the upper code into:
jmp 1234h:100 h
this is just a tiny example of self-modifying code, it's possible to do anything even without using DD (define double word ) and segment
overrides, in fact it is possible to use DB (define byte) only, because DW (define word) is just two DBs. it is important to remember that
Intel architecture requires the little end of the number to be stored at the lower address, for example the value 1234h is combined of two
bytes and it is stored in the memory as 3412 .
org 100 h
mov ax, 0
mov es, ax
mov bx, rr
push bx
rr:
mov ax, 1 ; return here
ret
end
Question:
It would be very useful to have the option of invoking a DOS shell at the build directory from the compile finished dialogue.
Solution:
The latest version of emu 8086 has external button that allows to launch command prompt or debug.exe with preloaded executable and it
also allows to run executables in real environment.
for previous versions of emu8086 you can download Microsoft utility called command prompt here , after the compilation click browse..., to
open C:\ emu8086\MyBuild folder in file manager, then right -click this folder and select "open command prompt here" from the pop-
up menu.
Question:
Answer:
Yes, it's possible to click the instruction line and click Set break point from Debug menu of the emulator.
It is also possible to keep a log similar to debug program, if you click View - > Keep Debug Log.
The break point is set to currently selected address (segment:offset).
The emulator will stop running when the physical address of CS:IP registers is equivalent to break point address (note: several effective
address may represent the same physical address, for example 0700:114 A = 0714 :000A)
Another way to set a break point is to click debug - > stop on condition and set value of IP register. The easiest way to get IP values is
from the listing under LOC column. To get listing click debug - > listing
In addition it' s possible to the emulator to stop on codition AX = 1234 h and to put the follwoing lines in several places of your code:
Question:
I am aware that 8086 is limited to 32 ,767 for positive and to -32,768 for negative. I am aware that this is the 16-bit processor , that was
used in earlier computer systems, but even in 8-bit Atari 2600 score counts in many games went into the 100,000s, way beyond 32 ,000.
Solution:
Here is the example that calculates and displays the sum of two 100-bit values (30 digits).
32 bits can store values up to: 4,294,967,296 because 2^ 32 = 4294967296 (this is only 10 decimal digits).
100 bits can hold up to 31 decimal digits because 2^ 100 = 1267650600228229401496703205376
(31 decimal digits = 100 binary digits = 100 bits )
; this example shows how to add huge unpacked BCD numbers (BCD is binary coded decimal).
; this allows to over come the 16 bit and even 32 bit limitation.
; because 32 digit decimal value holds over 100 bits!
; the number of digits in num1 and num2 can be easily increased.
ORG 100 h
; skip data:
JMP code
; 423454612361234512344535179521 + 712378847771981123513137882498 =
; = 1135833460133215635857673062019
; you may check the result on paper, or click Start , then Run, then type "calc".
; digit pointer :
XOR BX , BX
next_digit :
; add digits:
MOV AL, num1[ BX]
ADC AL, num2 [BX]
; store result :
MOV sum[BX], AL
LOOP next_digit
print_d:
MOV AL, sum[BX ]
; convert to ASCII char:
OR AL, 30h
MOV AH, 0 Eh
INT 10h
INC BX
LOOP print_ d
RET
END
With some more diligence it's possible to make a program that inputs 200 digit values and prints out their sum.
Question:
I'm making an interrupt counter; for that I am using 1 phototransister and sdk-86 board at college. I am not having this kit at home so I
have a problem to see the output.
here is issue.: when light on phototransister is on and off pulse is generated, this pulse comes just like the harwared iterrupt . my program
must to count these pulses continuously; for that I am using 8255 kit and SDK-86kit at college, but at home I don't have this equempent at
home. Am I able to emulate the output of real system? Perchanps, I have to develope 8255 device as an externel device in emu8086 ; but
how can I prog this device in vb? I am using ports: 30 h, 31 h, 32 h, and 33 h. I dont know vb...
Answer:
You don't have to know vb, but you have to know any real programming language apart from html/javascript. the programming language
must allow the programmer to have complete control over the file input/output operations , then you can just open the file c:\emu8086 .io
in shared mode and read values from it like from a real i/o port . byte at offset 30h corresponds to port 30 h, word at offset 33 h corresponds
to port 33h. the operating system automatically caches files that are accessed frequently, this makes the interaction between the emulator
and a virtual device just a little bit slower than direct memory -to-memory to communication. in fact , you can create 8255 device in 16 bit or
even in 32 bit assembly language.
Note: the latest version supports hardware interrupts: c:\ emu8086.hw , setting a none-zero value to any byte in that file triggers a
hardware interrupt. the emulator must be running or step button must be pressed to process the hardware interrupt. For example:
idle:
nop
jmp idle
Question:
Answer:
it's possible to use emu8086 integrated calculator to make these calculations (set show result to hex).
note: 10 h = 16
Question:
I would like to print out the assembly language program as well as the corresponding machine language code. How can I do so ?
Solution:
It is not possible to print out the source code directly from emu8086, but you may click file -> export to HTML... and print it from the
browser or even upload it to the server preserving true code colors and allowing others just to copy & paste it.
The corresponding machine code can be opened and then printed out by clicking view - > listing right after the successful assembling/
compilation or from the emulator's menu.
Question:
Answer:
It is possible to overwrite the default stub address for int 03h in interrupt vector table with a custom function. And it is possible to insert CC
byte to substitute the first byte of any instruction , however the easiest way to set a break point is to click an instruction and then click
debug - > set break point from the menu.
Editor hints:
65535 and -1 are the same 16 bit values in binary representation: 1111111111111111b
as 254 and - 2 have the same binary code too: 11111110b
Question:
It is good that emu8086 supports virtual devices for emulating the io commands. But how does the IO work for real? (Or: How do I get the
Address of a device e .g. the serial port)
Answer:
It is practically the same. The device conrolling is very simple. You may try searching for "PC PhD: Inside PC Interfacing". The only
problem is the price. It's good if you can afford to buy real devices or a CPU workbench and experiment with the real things. However, for
academic and educational purpoces, the emulator is much cheaper and easier to use, plus you cannot nor burn nor shortcut it. Using
emu8086 technology anyone can make free additional hardware devices. Free hardware easy - in any programming language.
Question:
How do I set the output screen to 40*25, so I dont have to resize it everytime it runs.
Answer:
mov ax, 0
int 10h
It's possible to change the colours by clicking the "options" button. The latest version uses yellow color to select lines of bytes when the
instruction in disassembled list is clicked , it shows exactly how many bytes the instruction takes. The yellow background is no longer
recommended to avoid the confusion.
Instead of showing the offset the emulator shows the physical address now. You can easily calculate the offset even without the calculator,
because the loading segment is always 0700 (unless it' s a custom .bin file), so if physical address is 07100 then the offset is 100 and the
segment is 700.
The file system emulation is still undergoing heavy checks, there are a few new but undocumented interrupts . INT 21 h/4Eh and INT
21h/4Fh. These should allow to get the directory file list.
Question:
Answer:
First of all, it's a directive which instructs the assembler to build a simple .com file. unlike instructions, this directive is not converted into any
machine code. com files are compatible with DOS and they can run in Windows command prompt , and it's the most tiny executable format
that is available.
Literally this directive sets the location counter to 256 (100h). Location counter is represented in source code as dollar. This is an example
of how location counter value can be accessed: MOV AX, $ the execution of this instruction will make AX contain the address of instruction
that put this address in it.... but usually, it's not something to worry about, just remember that org 100h must be the first line if you want
to make a tiny single segment executable file. note: dollar inside "$" or '$' is not a location counter, but an ASCII character. Location counter
has nothing to do with string terminating "$" that is historically used by MS-DOS print functions.
Question:
Answer:
It is very similar to org 100h. This directive instructs the assembler to add 7C00h to all addresses of all variables that are declared in your
program. It operates exactly the same way as ORG 100 h directive, but instead of adding 100 h (or 256 bytes) it adds 7C00h.
without ORG 100 h directive assembler produces the following machine code:
however with ORG 100 h directive assembler automatically updates the machine code to:
org 7C00h directive must be used because the computer loads boot records into the memory at address 0000:7C00.
If program is not using variable names and only operates directly with numeric address values (such as [2001 h] or [0000 :1232h]... etc,
and not var1, var 2...) and it does not use any labels then there is no practical use for ORG directive. generally it's much more convenient
to use names for specific memory locations (variables), for these cases ORG directive can save a lot of time for the programmer, by
calculating the correct offset automatically.
Notes:
ORG directive does not load the program into specific memory area.
Misuse of ORG directive can cause your program not to operate correctly.
The area where the boot module of the operating system is loaded is defined on hardware level by the computer system/BIOS
manufacture.
When .com files are loaded by DOS/prompt , they are loaded at any available segment, but offset is always 100h (for example
12C9:0100).
It is not recommended to use two neighbouring 16 bit ports , for example port 0 and port 1.
Every port has a byte length (8 bit ), two byte port (16 bit word) is emulated using 2 bytes or 2 byte ports.
When the emulator outputs the second word it overwrites the high byte of the first word.
; For example:
MOV AL, 34h
OUT 25 , AL
MOV AL, 12h
OUT 26 , AL
; is equvalent to:
MOV AX, 1234h
OUT 25 , AX
Question:
org 256
ret
bugi db 55
Answer:
To make the integrated assembler to generate more errors you may set:
STRICT_SYNTAX =true
in this file:
C:\emu8086 \emu8086.ini
By default it is set to false to enable coding a little bit faster without the necessity to use "byte ptr" and "word ptr" in places where it is
clear without these long constructions (i.e . when one of the operands is a register ).
Note: the settings in emu8086.ini do not apply to fasm (flat assembler). To use fasm add #fasm# or any valid format directive (valid for
emu8086 version 4.00-Beta -15 and above)
For differences between the integrated assembler (MASM/TASM compatible) and FASM see fasm_compatibility.asm
FASM does not require the offset directive. By default all textual labels are offsets (even if defined with DB/DW)
To specify a variable [ ] must be put around it.
To avoid conflicts between 8086 integrated assembler and fasm, it is recommended to place this directive on top of all files that are designed
for flat assembler:
#fasm#
Question:
I've installed emu 8086 on several computers in one of my electronics labs. Everything seems to work correctly when I am logged onto any
of the PC 's but , when any of the students log on, the virtual device programs controlled by the example ASM programs do not respond. ex;
using LED_display_test.ASM.
The lab is set up with Windows XP machines on a domain. I have admin privileges but the students do not. I tried setting the security setting
of C:\emu8086 so all users have full privileges but it did not help. Are there other folders that are in play when the program is running?
Solution:
In order for virtual devices to work correctly, it is required to set READ/WRITE privileges for these files that are created by the emulator in
the root folder of the drive C:
C:\emu8086 .io
c:\emu8086 .hw
These files are are used to communicate between the virtual devices and the emulator, and it should be allowed for programs that run under
students' login to create, read and write to and from these files freely.
To see simulated memory - click emulator 's "aux" button and then select "memory" from the popup menu.
EMU8086 Home
Migrating to Multicore? Make the move today with the Poly-Platform development kit www.polycoresoftware .com
C & C++ to Flowcharts Automatic convert C & C++ code to Visio, Word, Powerpoint flowchart www .fatesoft.com