x86组装新手:基本添加和存储数字问题

时间:2012-03-26 19:12:18

标签: assembly x86 masm32

你好,我是装配新手,我很难让两个部分的程序工作。我正在使用Visual Studio进行此x86程序集。

第一部分) 我的第一个目标是计算最多13个,在那里添加每个值。例如,0 + 1 + 2 + 3 ... + 13 = 91。我希望将总数存储在totall中。

第2部分) 其次,我希望从2 ^ 0到2 ^ 6的2的幂来计算。例如,0,1,2,4,8,32,64。 我想*我正在这样做,但我没有按照我的方式存储每个值。我想将它们存储在连续的内存位置。

到目前为止,我有这个,

.586
.MODEL FLAT

.STACK 4096

.DATA
num1 BYTE 13          ;Initialize number to count to
totall BYTE 0         ;Total of all counted numbers
temp BYTE 0           ;Temp for loop adding

shiftme BYTE 1        ;Start of counting 2^0 so I can reach 2^6

.CODE
main PROC
;code here

increment:            ;Increment label
inc temp              ;Increment temp by 1
mov eax, temp
add totall, eax       ;Add temp+totall and store in totall
cmp eax, num1         ;Compare for jump
jne increment         ;Jump if not equal

;this part should store each value 1,2,4,8,32.. in consecutive memory locat
shiftallthethings:    ;Shift label
shl shiftme, 1        ;Shifting bits to the left one
cmp shiftme, 64       ;Comparing for the jump
jne shiftallthethings ;Jump if not equal to

ret
main ENDP
END

帮助我理解的问题。

  • 如何在连续的内存位置存储值?
  • 我是否正确使用了跳转和标签说明?
  • 我是否需要使用像eax这样的特定寄存器来执行这些问题?为什么?

非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:2)

首先,回答你的问题:

  

如何在连续的内存位置存储值?

在MASM32中,您可以直接执行mov mov sum_addr, eax(只要数据类型具有相同的大小),也可以传递数据指针。在我写的示例中,指向total的指针被传递给函数。然后,该函数将值写入该指针指向的内存(即total的内容)。不太确定连续内存位置的含义。如果你的意思是指针运算,我也可以给你看一个例子。

  

我是否正确使用了跳转和标签说明?

是的,这似乎没问题。我使用的另一种选择是匿名标签。当标签很简单并且非常接近时,这是合适的。这是个人喜好。如果您觉得标签名称更合适,也可以随意使用。

  

我是否需要使用像eax这样的特定寄存器来执行这些问题?为什么呢?

MASM32遵循Win32(stdcall)的调用约定,所以你也可以这样做。在寄存器保存方面,这意味着除了eaxecxedx之外,所有函数都应保留寄存器,这些寄存器被认为是可存档的。如果需要超过4个字节,则返回值存储在eaxeaxedx中。


就您编写的代码而言,您遇到了一些问题,例如尝试将不同大小的数据类型相互移动。例如,如果您将byte移到dword,则必须先将其扩展为相同的大小。

mov eax, temp

这不会编译,因为temp只有1个字节长,而eax是4个字节。你可以这样做:

movzx eax, temp

在移动之前,这将零temp扩展。这是我抛出的一些代码,可能会教你一些东西。它使用宏(不确定你是否想要学习它们),但是否则会演示惯用的MASM32参数传递和返回值。

include \masm32\include\masm32rt.inc

.DATA

total DWORD 0         ;Total of all counted numbers

.CODE

; takes in address of total and writes the value there
sum PROC sum_addr:DWORD

xor eax, eax
xor ecx, ecx

  @@:
inc ecx
add eax, ecx
cmp ecx, 13
jnz @b

mov edx, sum_addr
mov dword ptr ds:[edx], eax
print ustr$(eax), 13, 10

mov edx, sum_addr
mov eax, dword ptr ds:[edx]
ret

sum ENDP

start:

push offset total          ; pass address of total
call sum
print ustr$(eax), 13, 10   ; demonstrating how to use return values

print ustr$(total), 13, 10 ; testing result got stored properly
ret

end start
END

代码未经过优化,但应易于理解。注意我是如何尝试尽可能多地使用寄存器的(如果我们有足够的寄存器,这比不断处理内存更有效。)