问题
my project I'm supposed to create a program that fills an array with an x number of fibbonacci numbers. In this case it's 47. I've got the programming set to get it the numbers etc, I just can't seem to get them into my array. Any help would be great as I'm sure i'm just off on my syntax. I'm debugging it in visual studio, so I guess that's masm? Thanks in advance.
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.data
fibba DWORD 47 DUP(?)
.code
main proc
mov eax,1 ;current number
mov ebx,0 ;last number in array
mov edi,0 ;array location
mov ecx,LENGTHOF fibba ;how many loops
L1:
mov [fibba+edi] ,eax ;move current into array
push eax ;move current into stack
add eax, ebx ;adding previous to current
pop ebx ;pulling last number used off stack
inc edi ;incrementing array location
loop L1
invoke ExitProcess,0
main endp
end main
回答1:
Use [fibba+edi*4]
or increment edi
by 4 (the width of a dword). You're currently doing 4B stores that overlap by 3B.
Related: my answer on Assembly Language (x86): How to create a loop to calculate Fibonacci sequence.
Using push eax/pop ebx is a novel way to solve the problem. It's not the most efficient, but it should work. Neat idea. Also, the loop instruction is slow, use dec ecx/jnz
(or a different loop condition, like cmp edi, fibba+47*4
) instead.
(in a comment)
Am I technically defining fibba as a word or as a double word? I should be using a doubleword. But at that point push pop wont work will it because push/pop is limited to 4 bytes.. Yeah?
You're reserving 47 * 4 bytes, with the fibba
label marking the start of it. A DWORD is 32 bits (4 bytes). In x86 asm terminology, a "word" is only 16 bits, because of its 16-bit heritage.
On most CPUs, the "natural" size of an integer is a word (e.g. 32 bits on MIPS, ARM, etc.), but not on x86. The "natural" size of an integer on x86 is 4 bytes / 32-bits, but it's called a dword (double-word). Anyway, you're not pushing/popping in fibba, you're using it to save/restore the full width of a register (which is also 4 bytes).
Microsoft's assembler has some "magic" where it looks at what directives you use after a label to imply an operand size for something like mov [fibba], 0
, but other assemblers require an explicit size because neither operand is a register. IMO this is a better way to think about it: memory doesn't inherently have any types, it's just a bag of bytes, and it's up to you as the asm programmer to get it right. That's why you didn't get any warnings for doing overlapping 4-byte stores offset by only 1 byte, you just got bogus data in memory.
来源:https://stackoverflow.com/questions/46751526/asm-language-pointer-to-an-array