标签: x86-16

NASM x86 16位寻址模式

我在指向一个地址时遇到了麻烦,并在我的情况下写了一个大小为byte的变量.这给了我错误"错误:无效的有效地址":

mov byte[AX], byte 0x0
Run Code Online (Sandbox Code Playgroud)

经过一些跟踪和错误后,我测试了相同但使用EAX.编译得很好:

mov byte[EAX], byte 0x0
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

x86 assembly nasm addressing-mode x86-16

5
推荐指数
1
解决办法
1000
查看次数

有效地址计算时间为8086/8088

我已经开始实现8086/8088,其目标是完全循环.我可以理解大多数指令的时钟周期数背后的原因,但我必须说我对有效地址(EA)计算时间感到困惑.

更具体地说,为什么计算BP + DI或BX + SI需要7个周期,但计算BP + SI或BX + DI需要8个周期?

我可以等待一定数量的周期,但我真的很想知道为什么存在这种1周期差异(以及为什么需要这么多周期才能进行任何EA计算,因为EA使用ALU来计算地址,寄存器之间的ADD只有3个周期).

x86 assembly cpu-architecture x86-16

5
推荐指数
1
解决办法
1196
查看次数

在8086指令集中使用ASSUME指令

在我的教科书中,它给出了ASSUME指令告诉汇编器用作物理段的逻辑段的名称.并且它使用从指定逻辑段的开头的位移来编码指令. 点击此处查看截图. 但是,这里当我在emu8086中执行这个汇编程序时,它会自动确定偏移/位移(即使在注释掉ASSUME语句之后).它是如何做到的?那么,ASSUME声明是多余的?

assembly emulation x86-16

5
推荐指数
1
解决办法
6927
查看次数

装配8086中的SAL/SAR与SHR/SAR

我正在学习汇编语言(特定于x86).我已经理解 SAL并且 SHL以类似的方式工作(清除lsb并将msb携带到CF)从这里开始在80x86中SHL和SAL之间的区别.

考虑到SHR并且SAR不以类似的方式操作(后者保持msb不变).

我想大概有一个明确的概念,为什么的功能移位算术右移 SAR定义不同右移 SHR,但在同一时间SHL ,并 SAL保持与类似的功能?

assembly opcode x86-16

5
推荐指数
1
解决办法
8569
查看次数

如何在16位汇编程序中传递/检索DOS命令行参数?

我正在为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命令行传递给我的程序.

assembly dos tasm 16-bit x86-16

5
推荐指数
2
解决办法
1792
查看次数

装配说明:AAA

我正在看伪代码: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 =>它是十进制的!".

我对代码的解释如下:

  • 在add指令之后,存储在AL寄存器中的值将为15(0Fh).
  • 由于它大于10,因此将向该值添加6,并且使用0Fh进行AND运算,这将导致1s值存储在AL寄存器中("AL =(AL + 6)AND 0FH;").AL寄存器的值现在应为05h.
  • 算法在AH寄存器中加一个,我假设是寄存器,因为我们对AL寄存器进行了ANDed和归零4位("AH =(AH + 1);").

但是,在运行"AH =(AH + 1);"行之前,没有提到存储在AH寄存器中的值.如果它被初始化为零,它只适用于20以下的数字.现在我们假设它被初始化为零,我希望结果存储为AH = 1和AL = 5,但评论说"; …

x86 assembly bcd x86-16 80286

5
推荐指数
1
解决办法
1263
查看次数

在CodeView中单步执行时,EBX的高位被清零

我有以下用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的上半部分也为零:

在此处输入图片说明

为什么实际上会发生?

x86 assembly masm code-view x86-16

5
推荐指数
1
解决办法
60
查看次数

如何在DOS程序集中正确挂接Interrupt 28h并将其还原?

我试图将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)

assembly dos interrupt x86-16

5
推荐指数
1
解决办法
197
查看次数

如何在Nasm程序中替换特定字符

我想用'#'字符替换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)

assembly nasm x86-16

5
推荐指数
0
解决办法
61
查看次数

在引导加载程序启动时读取堆栈安全吗?

背景

我正在尝试制作一个适用于两种架构的引导加载程序: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,spss值都没有指定,所以这个命令读取谁知道什么。

我的问题是:

  • 在实践中,我可以假设它们要么指向有效的堆栈,要么都设置为某个占位符,例如0x0000:0x0000or 0xffff:0xffff
  • 可能ss:sp指向读取不安全的内存映射硬件寄存器?如果是的话,如果我读了它们,会发生什么更糟糕的事情?我不想意外损坏笔记本电脑。
  • 可能ss:sp指向不可用的内存,即可能pop di触发总线错误?如果是,BIOS 将如何从中恢复,即它将重新启动、显示消息或执行其他操作?

x86 assembly bootloader x86-16 stack-pointer

5
推荐指数
0
解决办法
130
查看次数