为什么我从mov ax,bx + si + 1得到零?

Ita*_*209 2 assembly x86-16 emu8086

    mov     ax,10
    mov     bx,4
    mov     si,ax
    mov     ax,bx+si+1
    LEA     ax,[bx+si+1]
Run Code Online (Sandbox Code Playgroud)

当我一起添加bx,si和1并移动到ax时,结果为0.在下一行,当我使用LEA时,它可以工作,我得到15.

使用移动时为什么我会变零?

Jos*_*uez 5

你的问题是:"为什么我从mov ax,bx + si + 1得到零?".很难给出准确的答案,因为您忘记告诉您使用的是什么编译器,而您的代码段不包含数据段,因此我们无法查看您的数据.我们可以做的是使用数据段中的一些数字测试您的代码并查看结果:

.model small
.stack 100h
.data    
xy db 0A0h,0A1h,0A2h,0A3h,0A4h,0A5h,0A6h,0A7h,0A8h,0A9h,0AAh,0ABh,0ACh,0ADh,0AEh,0AFh,0B0h
.code
  mov  ax, @data
  mov  ds, ax

  mov  ax, 10
  mov  bx, 4
  mov  si, ax
  mov  ax, bx+si+1       ;??? #1 (EXPLANATION BELOW ?)
  LEA  ax, [bx+si+1]     ;??? #2 (EXPLANATION BELOW ?)
Run Code Online (Sandbox Code Playgroud)

让我们来说明这里发生的事情:

在此输入图像描述

这是怎么回事:

#1由于基址寄存器(的存在bx)和一个变址寄存器(si)之和被解释为一个存储器寻址,所以代码获取在存储器位置中的数据15,ax寄存器大小是2个字节,所以结果是,ax得到从内存位置15开始的2个字节,在我们的数据段中,这2个字节是0AFh0B0h.al是低位字节ax,所以第一个字节(0AFh)存储在那里,高位字节ah得到第二个字节(0B0h),这就是ax变成的方式0B0AFh.

#2我们说基址寄存器bx和索引寄存器的存在si被解释为存储器寻址,因此[bx+si+1]指向存储器位置15(0AFh).指令lea代表load effective address,其目的是从数据段内部获取地址.您的代码行正在获取内存位置15(0AFh)的有效地址,即15.

这么多理论需要一个演示,这里是:

接下来是EMU8086的屏幕截图:蓝色箭头指向原始代码行,绿色箭头指向解释时的代码行(作为内存寻址),红色箭头显示寄存器中的效果ax(B0AFh) .

在此输入图像描述

现在是下一条指令的屏幕截图:蓝色箭头指向原始代码行,绿色箭头指向解释时的代码行(注意它与前一行相同),红色箭头显示效果在寄存器ax(0Fh).

在此输入图像描述

最后,让我们在Visual Studio 2013中测试代码:下一个屏幕截图证明这mov ax, bx+si+1是无效的,另一行提供与EMU8086(ax= 0FH)相同的结果:

在此输入图像描述

所以,"你为什么从mov ax,bx + si + 1得到零?" 因为数据段内的内存位置可能为零.你可能认为这bx+si+1会给你一个正常的数字,15,但现在你知道使用基数和索引寄存器将被解释为内存寻址,所以你不会得到数字15但是内存位置15中的数据.

  • 所以EMU8086需要在谷仓和射击后面采取的另一个原因. (6认同)