【问题标题】:What am I doing wrong? (Simple Assembly Loop)我究竟做错了什么? (简单组装循环)
【发布时间】:2010-02-03 06:10:22
【问题描述】:

它不会让我发布图片。顺便说一句,Reddit.programming 的某个人把我送到了这里。所以谢谢!

TITLE MASM Template

; Description
;
; Revision date:

INCLUDE Irvine32.inc
.data
myArray BYTE 10, 20, 30, 40, 50, 60, 70, 80, 90, 100

.code
main PROC
    call Clrscr
    mov esi, OFFSET myArray
    mov ecx, LENGTHOF myArray
    mov eax, 0
L1:
    add eax, [esi]
    inc esi
    loop L1
    call WriteInt
    exit
main ENDP
END main

结果:

-334881242

【问题讨论】:

  • 你能发布代码吗?我几乎看不出来。
  • 我没有发现任何明显的错误。也许您的 WriteInt 函数应该在循环内?并确保它只打印一个字节的值,因为它似乎打印了一个 32 位的值。
  • i.imgur.com/gjUbV.jpg 这是完整的图像。我炸得很厉害
  • 它现在在做什么,你期望它做什么?请发布一个体面的问题,以便我们可以真正帮助您。
  • 它应该将数组中的值相加,导致输出为550

标签: loops assembly x86 masm irvine32


【解决方案1】:

您必须将值转换为字节指针而不是 32 位指针。

改变

add eax, [esi]

add eax, byte ptr [esi]

【讨论】:

  • 那不行:错误A2022:指令操作数必须相同大小
【解决方案2】:

您正试图从字节表中获取 DWORD,因此 masm 会给您一个错误。在此处使用 BYTE PTR 强制字节大小会给您一个 masm 错误(无效的操作数或类似的东西),因为您不能直接在 DWORD 中添加一个字节。

但是仍然有几种方法可以做你想做的事。 这是一个需要额外寄存器 (EDX) 的方法:

(...)
    mov edx, 0         ; We want the upper 3 bytes to zero.
    mov eax, 0

L1:
    mov dl, [esi]      ; Inject one byte from the table,
    add eax, edx       ;  upper bytes still zero, so EDX has your byte value.
(...)

【讨论】:

    【解决方案3】:
    包括 Irvine32.inc 。数据 myArray BYTE 10、20、30、40、50、60、70、80、90、100 。代码 主进程 调用 Clrscr mov esi, 偏移 myArray mov ecx, LENGTHOF myArray xor eax, eax L1: 添加 eax,字节 ptr [esi] 公司 循环 L1 调用 WriteInt 出口 主要ENDP 结束主

    我假设,WriteInt 使用 EAX 中的参数来打印结果,因为代码失败,因为您使用 32 位指针指向 ESI 寄存器中数据的偏移量,请将其更改为byte ptr 以获得正确的 8 位(一个字节)。此外,XOR 的使用将比 MOV 寄存器的 MOV 指令更快,那么代码应该可以工作......

    希望这会有所帮助, 最好的祝福, 汤姆。

    【讨论】:

    • add eax, byte ptr [esi] 会抛出错误:error A2022:instruction operands must be the same size
    【解决方案4】:

    好的,事情就是这样:

    我的猜测是 WriteInt 期望 EAX 中的 32 位有符号值。因此你可以这样做:

    movzx eax, BYTE PTR [esi]
    inc esi 
    call WriteInt 
    
    loop L1 
    -- or --
    dec ecx
    jnz L1
    

    或者,如果您确定 WriteInt 不会触及 EAX,您可以这样做:

    xor eax,eax ; clear EAX
    L1:
    lodsb ; loads a byte into AL and increments ESI for you
    call WriteInt
    loop L1
    

    【讨论】:

      猜你喜欢
      • 2015-08-26
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 2014-06-15
      相关资源
      最近更新 更多