我有一个小的8086模拟器,我有一个长期的错误2年,现在AF在子内部表现不正常并添加说明.
我目前计算其值的方法是8位数和减法:
uint8_t base=... , subt=...
base=base&0xF;
subt=subt&0xF; //isolate bottom nibble
if((int16_t)base-subt>7 || (int16_t)base-subt<-7){
flags.af=1;
}else{
flags.af=0;
}
Run Code Online (Sandbox Code Playgroud)
(假设有一个指令sub base,subt)
并添加它是这样的:
uint8_t base=... , adder=...
base=base&0xF;
adder=adder&0xF; //isolate bottom nibble
if(base+adder>7 || base+adder<-7){
flags.af=1;
}else{
flags.af=0;
}
Run Code Online (Sandbox Code Playgroud)
(对于像这样的指令add base,adder)
如何正确计算模拟器中的AF标志以获取此类指令?
假设x是一个寄存器,其值不知道.我必须让x=2a+3b地方a和b有未知值.
我可以用8086个汇编指令mov,add,sub,neg只.mul不允许使用该指令,并且仅限4条指令.
它甚至可能吗?
我正在用汇编编写引导加载程序,它似乎在 qemu、bochs 和 virtualbox 上运行良好。但是,它并没有在真实硬件上加载内核(似乎)。
引导加载程序首先将一个字符写入视频内存(用于调试),然后从驱动器读取扇区 2 并远跳转到内核。然后内核将一些字符写入视频内存。
在真机上,我在屏幕上看到引导加载程序中的字符,它挂在那里(闪烁的插入符号)。
我已经尝试将 DS、ES、SI 设置为零,并且我也在设置堆栈段。
我正在使用 bios int 13 function 2 从驱动器读取扇区 2。我有点怀疑它与驱动器编号有关。我都尝试使用在启动时(在 dl 中)传递给引导加载程序的驱动器号,并将其手动设置为 0x0、0x80 和 0x81。
我注意到的一件奇怪的事情是,我用来接近跳转的标签神奇地获得了正确的地址。使用 objdump 我看到例如:jmp 0x2,而使用 gdb 和 qemu,它说:jmp 0x7c02。CS 和所有其他段寄存器为零。无论我在链接中使用 -Ttext 0x0 还是 -Ttext 0x7c00,引导加载程序在所有模拟器上都能正常工作。当我与 -Ttext 0x7c00 链接时,objdump 说 jmp 0x7c02。
编辑,引导加载程序如下所示:
.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw $0x8000, %ax
movw %ax, %ss
movw $0, %sp
movb $2, …Run Code Online (Sandbox Code Playgroud) 我在8086处理器的汇编中编写了一个游戏,并在名为DOSBox的DOS模拟器上运行它.
现在我想向其他人展示游戏而不必下载模拟器.基本上,我想将8086程序集编译为现代操作系统的可执行文件.这可能,还是应该将其转换为另一种汇编语言?如果是这样,有没有办法自动进行此转换?
为什么以下代码不X使用emu8086中的Assignment Directive(=)为符号赋值:
.model small
.data
X = 8
.code
.startup
mov ax, @data
mov ds, ax
mov bx, X
X = 6
mov bx, X
mov ah, 02h
mov dx, bx
add dx, 48
int 21h ; It should display 6 but instead it display 8.
mov ah, 04ch
int 21h
end
Run Code Online (Sandbox Code Playgroud) 由于原始的8086和8088没有针对非法指令的软件例外,因此在输入此类指令(例如“ FF FF”(不是操作码))时会如何表现?它们是否失速,是否会自行复位,并可能在其控制总线上发出特殊的循环指示?
好的,所以我尝试在使用IDE Turbo C ++ 3.0的模拟环境(DosBox)中应用双重缓冲技术,我正在运行Windows 7 64bit(不确定是否重要),而且我不知道如何正确执行缓冲例程在这种环境下。
我遇到的主要问题是我似乎无法执行以下赋值语句:
double_buffer = (byte_t far*)farmalloc((unsigned long)320*200);
(请注意320和200是屏幕尺寸)...我只是得到NULL分配。
我尝试将DosBox的默认RAM使用率更改为32,而不是16,但这没有任何作用。我不确定这是模拟器还是Turbo C的代码出了问题。(请注意,它符合要求)。
这是我在网上找到的示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <string.h>
#include <alloc.h>
typedef unsigned char byte_t;
byte_t far* video_buffer = (byte_t far*)0xA0000000;
void vid_mode(byte_t mode){
union REGS regs;
regs.h.ah = 0;
regs.h.al = mode;
int86(0x10,®s,®s);
}
void blit(byte_t far* what){
_fmemcpy(video_buffer,what,320*200);
}
int main(){
int x,y;
byte_t far* double_buffer;
double_buffer = (byte_t far*)farmalloc((unsigned long)320*200);
if(double_buffer == NULL){
printf("sorry, not enough memory.\n");
return 1; …Run Code Online (Sandbox Code Playgroud) 给出的是英特尔8086处理器的汇编程序,它在数组中添加数字:
.model small
.stack 100h
.data
array dw 1,2,3,1,2
sum dw ?,", is the sum!$"
.code
main proc
mov ax,@data
mov ds,ax
mov di,0
repeat:
mov ax,[array+di]
add sum,ax
add di,2 ; Increment di with 2 since array is of 2 bytes
cmp di,9
jbe repeat ; jump if di<=9
add sum,30h ; Convert to ASCII
mov ah,09h
mov dx,offset sum ; Printing sum
int 21h
mov ax,4c00h
int 21h
main endp
end main
Run Code Online (Sandbox Code Playgroud)
上面的程序使用"base + index"寻址模式添加数组的数量.
可以通过以下方式执行相同的操作:
mov ax, …Run Code Online (Sandbox Code Playgroud) 这是一个愚蠢的问题,但是...我最近玩过djgpp并且很惊讶可以编译/链接现代c ++ 17代码到32位dos二进制文件.Mingw涵盖了win32和win64.但就win16而言,存在一个巨大的漏洞.有没有能够生成16位代码的c ++ 17编译器(用于dos,windows或任何其他操作系统)?