为什么寄存器ax中的存储器整数的正确总和而不是寄存器eax?

时间:2017-10-11 19:51:26

标签: visual-studio assembly x86 nasm

鉴于此计划 - 我正在帮助的学生计划 -

        global  _start

        section .text
_start:
        mov    ebx, people 
        mov    eax, [ebx + 2]
        add    eax, [ebx + 4]
        add    eax, [ebx + 6]
        add    eax, [ebx + 8]
        mov    ebx, [constant]
        div    bx

section .data

average     dw 0
constant    dw 5
people      dw 0, 10, 25, 55, 125

在将这个从Visual Studio移植到Linux机器以找出问题所在时,我遇到了一些问题:

1)为什么gdm在发出print $ax时显示总和255,但是在print $eax命令发出时会出现大量数字?那是因为我们添加了单词值而不是长字值吗?

我确实尝试添加到ax而不是eax,并获得了相同的结果。当我试图将初始值移动到ax时,我收到了搬迁投诉。这就是我使用eax的原因。

2)为什么使用div bx时商43,但如果使用div ebx,我的答案是错误的?

顺便说一句,我相信我找到了原始问题,这是一个整数溢出。第10行 - mov ebx, [constant] - 最初为mov ebx,constant,但未导致将5移至bx。

1 个答案:

答案 0 :(得分:3)

一些问题

  1. 所有数据都定义为 word ,但代码将其视为 dword

  2. 在分割之前,您需要通过DXEDX来延长红利。

  3. 虽然数组中的第一个值为零,但最好还是将它包含在代码中。如果数据发生变化,至少代码仍然有效!

  4. 解决方案

    1. 保持数据16位并相应编程

      mov    edx, people
      mov    ax, [edx]
      add    ax, [edx + 2]
      add    ax, [edx + 4]
      add    ax, [edx + 6]
      add    ax, [edx + 8]
      xor    dx, dx
      div    word ptr [constant]      ;Divide DX:AX by 5
      ...
      constant    dw 5
      people      dw 0, 10, 25, 55, 125
      
    2. 将数据设为32位并相应编程

      mov    edx, people
      mov    eax, [edx]
      add    eax, [edx + 4]
      add    eax, [edx + 8]
      add    eax, [edx + 12]
      add    eax, [edx + 16]
      xor    edx, edx
      div    dword ptr [constant]     ;Divide EDX:EAX by 5
      ...
      constant    dd 5
      people      dd 0, 10, 25, 55, 125
      
    3. 了解我是如何避免使用EBX的?

      • 除法可以直接从记忆中使用它的分隔符。
      • EDX寄存器(无论如何参与分割)也可以同样精确地处理内存。

      少注册blobber是一件好事!