我在指向一个地址时遇到了麻烦,并在我的情况下写了一个大小为byte的变量.这给了我错误"错误:无效的有效地址":
mov byte[AX], byte 0x0
Run Code Online (Sandbox Code Playgroud)
经过一些跟踪和错误后,我测试了相同但使用EAX.编译得很好:
mov byte[EAX], byte 0x0
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
我已经开始实现8086/8088,其目标是完全循环.我可以理解大多数指令的时钟周期数背后的原因,但我必须说我对有效地址(EA)计算时间感到困惑.
更具体地说,为什么计算BP + DI或BX + SI需要7个周期,但计算BP + SI或BX + DI需要8个周期?
我可以等待一定数量的周期,但我真的很想知道为什么存在这种1周期差异(以及为什么需要这么多周期才能进行任何EA计算,因为EA使用ALU来计算地址,寄存器之间的ADD只有3个周期).
在我的教科书中,它给出了ASSUME指令告诉汇编器用作物理段的逻辑段的名称.并且它使用从指定逻辑段的开头的位移来编码指令. 点击此处查看截图. 但是,这里当我在emu8086中执行这个汇编程序时,它会自动确定偏移/位移(即使在注释掉ASSUME语句之后).它是如何做到的?那么,ASSUME声明是多余的?
我正在学习汇编语言(特定于x86).我已经理解
SAL并且 SHL以类似的方式工作(清除lsb并将msb携带到CF)从这里开始在80x86中SHL和SAL之间的区别.
考虑到SHR并且SAR不以类似的方式操作(后者保持msb不变).
我想大概有一个明确的概念,为什么的功能移位算术右移 SAR定义不同右移 SHR,但在同一时间SHL ,并 SAL保持与类似的功能?
我正在为MS-DOS编写一些小工具.现在我正在写一个Shutdown.com,比如Windows XP和更高版本.我已经编写了整个代码,现在我只需要从DOS传递参数.
我需要将参数"-r"传递给reboot,将"-s"传递给shutdown.
我该怎么做?
我在Windows 98上使用TASM(Turbo Assembler 4.1)进行链接和编译.我正在寻找一种非常简单的方法,如果可能的话,还是一个.COM程序.我看起来与C语言中的ARGV和ARGC完全相同,但对于16位汇编...
shutdown -r 将重启shutdown -s 将关闭请记住,我已经知道如何重新启动以及如何关闭PC.
我只需要学习如何将参数从MS-DOS命令行传递给我的程序.
我正在看伪代码:BCD指令的隐藏能力.以下是该网站内容的片段:
那么,让我们来看看AAA的作用.这是伪代码等价物(来自英特尔):
IF ((AL AND 0FH) > 9) OR (AF = 1)
THEN
AL = (AL + 6) AND 0FH;
AH = (AH + 1);
AF = 1;
CF = 1;
ELSE
AF = 0;
CF = 0;
FI;enter code here
Run Code Online (Sandbox Code Playgroud)
对于像这样的典型英特尔文档兼容用途,这是正确的:
mov al,6
add al,9 ;al=15=0Fh
aaa ;al=21=15h => it's in decimal!
Run Code Online (Sandbox Code Playgroud)
上面的算法似乎没有在代码中给出结果,所以我假设这里省略了一些步骤.评论说明如下:"al = 21 = 15h =>它是十进制的!".
我对代码的解释如下:
但是,在运行"AH =(AH + 1);"行之前,没有提到存储在AH寄存器中的值.如果它被初始化为零,它只适用于20以下的数字.现在我们假设它被初始化为零,我希望结果存储为AH = 1和AL = 5,但评论说"; …
我有以下用MASM为i386处理器编写的简单程序:
TITLE BLA
.MODEL SMALL
.386
.STACK
.DATA
.CODE
MAIN PROC FAR
.STARTUP
MOV EBX,0FFFFFFFFH; (1)
MOV EAX,0EEEEEEEEH; (2)
.EXIT
MAIN ENDP
END
Run Code Online (Sandbox Code Playgroud)
我对EBX寄存器的行为感到困惑。在(1)指令之后,EBX设置为1-s:
执行(2)指令不仅会将值加载到EAX中,而且在EBX的上半部分也为零:
为什么实际上会发生?
我试图将Interrupt 28h的处理程序设置为我自己的例程,恢复所有涉及的寄存器和标志,并恢复原始的Interrupt处理程序。我在VirtualBox中的DOSBox和MS-DOS 6.22下使用NASM汇编器。
我已经考虑过调试,但是在TSR程序上进行调试听起来似乎是不可能的。我尝试将数据段推到代码段上,并保存原始数据段以供以后还原,但是即使还原了数据段后,它似乎仍挂起了计算机。
section .text ;Code Section
org 100h ;DOS Executable Start
mov ah,35h ;Get Interrupt Vector
mov al,28h ;Of Interrupt 28h
int 21h ;Call DOS Kernel
push cs ;Push Code Segment
pop ds ;Onto Data Segment
mov [oldseg],es ;Save Old Interrupt Vector Segment
mov [oldoff],bx ;Save Old Interrupt Vector Offset
mov ah,25h ;Set Interrupt Vector
mov dx,resstart ;To Resstart
int 21h ;Call DOS Kernel
mov dx,resend ;Set Data Offset to Resend
sub dx,resstart ;Subtract Resstart
shr dx,4h ;Shift …Run Code Online (Sandbox Code Playgroud) 我想用'#'字符替换dbyte中的空格,并且db应该通过堆栈传递给过程。
我已经写了下一个代码片段,并且替换可以正常工作,但是我不明白如何func正确地将db传递给过程。
org 0x100
push array
call func
mov bp, sp
mov bx, [bp]
ret
loop:
mov al, byte[bx+si]
cmp al, 0
jz func
cmp al , ' '
jnz loop
mov byte[bx+si], '#'
inc si
jmp loop
ret
func:
push bp
mov bp, sp
mov bx, [bp + 4]
call loop
mov [bp + 4], bx
pop bp
ret 4
array db "a b c", 0
Run Code Online (Sandbox Code Playgroud) 我正在尝试制作一个适用于两种架构的引导加载程序:x86 和 PDP-11。主操作系统是为 PDP-11 兼容机器编写的,但从 x86 启动也应该可以工作,启动模拟器。
AFAIK,如果最后两个字节是, x86 加载第一个磁盘扇区0x7c00并跳转到那里。相反,如果第一个命令是且最后两个字节是 ,则 PDP-11 兼容机将第一个扇区加载到(八进制)并执行它。然而,由于一些硬件细节的原因,加载的数据实际上是颠倒的——例如,x86 读取的数据,另一台机器读取的数据。在这种情况下,这在某种程度上是一个功能,因为如果我制作最后两个字节,它们将适用于两台机器。0x55 0xaa0o20000NOP0xaa 0x550x120xed0x55 0xaa
总之,PDP-11兼容机需要前两个字节包含NOP命令,即0o000240,或0x00a0。数据被反转,因此 x86 实际上会读取0xff5f。
0x5f是 x86 中的真实命令。不幸的是,它是pop di. AFAIK,sp和ss值都没有指定,所以这个命令读取谁知道什么。
我的问题是:
0x0000:0x0000or 0xffff:0xffff?ss:sp指向读取不安全的内存映射硬件寄存器?如果是的话,如果我读了它们,会发生什么更糟糕的事情?我不想意外损坏笔记本电脑。ss:sp指向不可用的内存,即可能pop di触发总线错误?如果是,BIOS 将如何从中恢复,即它将重新启动、显示消息或执行其他操作?