我究竟做错了什么? (简单装配循环)

时间:2010-02-03 06:10:22

标签: loops assembly x86 masm irvine32

http://imgur.com/gjUbV.jpg

它不会让我发布图片。顺便说一下,来自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

4 个答案:

答案 0 :(得分:4)

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

更改

add eax, [esi]

add eax, byte ptr [esi]

答案 1 :(得分:1)

你试图从一个字节表中获取一个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.
(...)

答案 2 :(得分:0)

好的,这就是:

我的猜测是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

答案 3 :(得分:0)

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
    xor eax, eax
L1:
    add eax, byte ptr [esi]
    inc esi
    loop L1
    call WriteInt
    exit
main ENDP
END main

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

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