Assembly 汇编语言代码问题

Assembly 汇编语言代码问题,assembly,Assembly,我在自己的时间学习汇编语言,并试图解决以下问题。我写的代码,但它不会工作 编写一个程序,使用循环计算Fibonacci数列的前七个值,该数列由以下公式描述:Fib1=1,Fib2=1,Fibn=Fibn-1+Fibn-2 我需要用汇编语言编写这个程序。使用程序模板中的注释作为用汇编语言编写代码的说明。我希望程序按照以下编程逻辑用汇编语言编写: .data ;declare an array .code main proc ;move 0 into ebx to initialize ;move

我在自己的时间学习汇编语言,并试图解决以下问题。我写的代码,但它不会工作

编写一个程序,使用循环计算Fibonacci数列的前七个值,该数列由以下公式描述:Fib1=1,Fib2=1,Fibn=Fibn-1+Fibn-2

我需要用汇编语言编写这个程序。使用程序模板中的注释作为用汇编语言编写代码的说明。我希望程序按照以下编程逻辑用汇编语言编写:

.data
;declare an array 
.code
main proc
;move 0 into ebx to initialize
;move 1 into edx to store the first Fib value
;move edx into an array ; store the first Fib value

; prepare to loop
; loop counter for 6 more values
; move esi,4
; array index for 3rd Fib value

L1:
;move ebx into eax
;add edx and eax
;move edx into the array of esi
; eax = ebx 
; eax = eax + edx 
; store the Fib value
;move edx into ebx
; prepare for next iteration
;move eax into edx
;add 4 to esi
;Loop  L1

invoke  ExitProcess,0
我的代码:

ExitProcess PROTO

.data

numbers DWORD 10 DUP (?)

.code
main PROC
    mov ebx,0
    mov edx,1
    mov numbers,edx

    mov ecx,6
    mov esi,4

L1:
    mov eax,ebx
    add eax,edx
    mov esi,OFFSET numbers
    mov [esi],edx
    mov eax,ebx
    add eax,edx
    mov edx,ebx
    mov eax,edx
    add esi,4
Loop L1

    call ExitProcess
main ENDP
END
我将代码编辑为以下内容:

ExitProcess PROTO

.data

numbers DWORD 10 DUP (?)

.code
main PROC
    mov ebx,0
    mov edx,1
    mov numbers,edx

    mov ecx,10
    mov esi,4
    mov esi,OFFSET numbers

L1:
    mov eax,ebx
    add eax,edx
    mov [esi],edx
    mov ebx,edx
    mov edx,eax
    add esi,4
    Loop L1

    call ExitProcess
main ENDP
END

当我逐步浏览代码时,eax寄存器和edx寄存器将显示斐波那契序列值:1、2、3、5、8、13等。但是,代码是否将eax寄存器或edx寄存器值存储在数字数组中?如果没有,我怎么做

这是一行有效的代码吗?它是否将edx值存储在数字数组中

mov numbers,edx

如何在数字数组中存储eax或edx值?

代码中的一些问题:

mov numbers,edx
mov esi,OFFSET numbers
mov [esi],edx
这将在每次写入之前初始化esi,因此您将一直覆盖元素编号[0]

mov eax,ebx
add eax,edx
mov edx,ebx
mov eax,edx
这没有多大意义。。。首先计算eax=ebx+edx。。。第二次eax已经包含前几行中的值

然后你做eax=edx=ebx;即,将ebx复制到eax和edx中 你可能想用另一种方式,比如:mov ebx,edx mov edx,eax

从原始注释中移动esi,4没有什么意义,它会有一些意义,因为添加esi,4,您是否已经像下一个代码一样在esi中有了数字地址

但看起来您不明白地址是什么,所以在存储Fib值时,您会一次又一次地加载地址。整个要点是只将esi设置一次到数组开头,然后在每次写入后更新指针以指向下一个可用空间

总的来说,在每一条指令之后,找一些调试器,开始一步一步地观察寄存器和内存,将其与每一条指令描述进行比较,直到您熟悉它们的功能为止,从代码中看,您不知道这些指令实际上在做什么

现在试着理解这一点:

    mov   esi,OFFSET numbers  ; esi = target array address
    mov   ecx,7    ; produce seven numbers
    xor   ebx,ebx  ; ebx = 0 F(-1)
    mov   edx,1    ; edx = 1 F(0)
    jmp   store_number
loop1:
    add   ebx,edx  ; ebx: F(n) = edx: F(n-1) + ebx: F(n-2)
    xchg  ebx,edx  ; ebx: F(n-1), edx: F(n)
store_number:
    mov   [esi],edx ; array_pointer[0] = F(n)
    add   esi,4     ; ++array_pointer
    loop  loop1
还要注意有多少指令在做纯纸公式的功Fn=Fn-1+Fn-2,还有7个数字,还有多少指令只是为了支持这个东西。你可能不同意,但我想说的是。50%是支持cruft,大部分是直接纸张->代码重写

在学习汇编时,请记住这一点,首先要确保你非常清楚地知道你想在公式级别上实现什么,然后再尝试做到这一点。。。仅在绝对必要时添加支持代码。不要只是随便写一些指令,因为这看起来是个好主意,或者你以前就是这样写的。指令要么做你想做的事情,要么把它删掉

根据评论编辑:

mov esi,偏移量编号将符号编号的地址存储到esi中。如果将数字声明为BYTE或DWORD,地址指向分配的内存的第一个字节的第一个位置,这并不重要

字节/dword/dup对于分配足够的总空间很重要,但不会影响地址本身

mov[aaa],vvv将值vvv存储在地址aaa处的内存中,以查看可能的组合

所以mov[esi],在mov-esi之后的edx,偏移量数字将把每个值存储在数字[0]处。在调试器中,查看esi是如何通过该mov esi、偏移量数字每次重置的

请不要使用怪癖语法mov numbers,edx,它在模拟MASM怪癖模式时仅在MASM和TASM中将值存储到数字数组中,在适当的英特尔语法中,[]的使用表示指针/地址的解引用,因此在读取源代码时很容易判断指令是否仅使用寄存器/立即数,或者如果它确实访问内存。lea reg,[address]是一个例外,它不访问内存,只计算地址。在NASM中,mov数字edx根本不会编译,而mov edx数字不会从数组中加载第一个值,但MASM/TASM中的地址本身必须在符号之前写入偏移量

所以

代码是否将eax寄存器值存储在数字数组中

mov numbers,edx

不,它只覆盖第一个数字[0]值。

堆栈溢出不是“请给我代码”类型的网站。下次填写代码时不要删除注释。也许您可以将它们压缩一点,但保留它们以供参考和调试。mov编号,edx在模拟MASM的MASM TASM中也是有效的。它编译成mov DWORD PTR[ds:偏移量编号],edx以详细的技术方式准确描述它。它是有效的,但令人困惑和困惑,因为它对源代码的读取器隐藏了[]内存访问!如果您调试它并观察内存和esi值,以及c,那么您的新编辑几乎是正确的,只是有一点小问题
如果将其与偏移量编号进行比较,您将很快修复它,您已接近。顺便说一句,还有其他方法可以写入这些值,使用esi作为索引/偏移量,而不是将地址写入数字。。。那么movesi,4-between有意义,偏移到数字[1]元素。。。写指令是mov numbers[esi],edx不确定我是否使用了MASM语法,就像mov[OFFSET numbers+esi],edx,希望这是有意义的?我如何看到偏移量的值?当我调试时,我有一个监视列表,这样我可以看到寄存器值,我有一个打开的内存窗口,这样我可以看到数组中的值。我不知道如何观察偏移量的变化。你是说观察esi值的变化,因为我将数组指向esi?我想我只看到esi值的内存地址改变了4个字节。ExitProcess协议数据编号DWORD 10 DUP.code主程序mov ebx,0 mov edx,1 mov编号,edx mov ecx,10 mov esi,4 L1:mov eax,ebx add eax,edx mov esi,偏移量mov[esi],edx mov ebx,edx mov edx,eax add esi,4循环L1调用ExitProcess main ENDP End当我单步执行代码时,eax寄存器将显示斐波那契序列值:1、2、3、5、8、13等。但是,代码是否将eax寄存器值存储在数字数组中?如果不是,我该怎么做。@ISM34当您单步执行代码时,请同时打开“内存”视图,并将其移动到数字地址,以便您可以立即观察每次写入时内存值的变化。但看起来你不明白地址是什么-仍然是正确的