2016-10-11 164 views
-3

我在学习汇编语言并尝试解决以下问题。我编写了代码,但它不起作用。汇编语言代码问题

编写一个程序,该程序使用循环来计算由以下公式描述的斐波那契数列的前七个值:Fib(1)= 1,Fib(2)= 1,Fib(n)= Fib (n-1)+ Fib(n-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寄存器将显示Fibonacci序列值:1,2,3,5,8,13等。但是,代码是否将eax寄存器或edx寄存器值存储在数字a中rray?如果不是,我该怎么做。

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

mov numbers,edx 

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

+0

堆栈溢出不是一个“请给我teh codez”类网站。 – fuz

+1

下次在填写代码时不要删除注释。也许你可以压缩他们一些,但保持它们的参考和调试。 – Ped7g

+0

'mov numbers,edx'在MASM中有效(TASM也在模拟MASM)。它编译为'mov DWORD PTR [ds:OFFSET numbers],edx'(详细描述它的技术方式)。这是有效的,但令人困惑和难堪,因为它隐藏了源码阅读器的'[]'(内存访问)!你的新编辑几乎是正确的,只要稍加捕捉,如果你要调试它并观察内存和esi值,并将它与'OFFSET数字'进行比较,你很快就会修复它,你就近了。 – Ped7g

回答

0

一些代码中的问题:

mov esi,OFFSET numbers 
mov [esi],edx 

这将初始化esi提前每个写的,所以你会被改写元素“numers [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”从原来的评论没有意义,它将使一些意义,因为add esi,4,你会已经在esinumbers地址(如下面的代码一样)。

但它看起来像你不明白什么地址是,所以在“存储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 

同样要注意许多指令都在做纯纸式工作(“F(N)= F(N-1)+ F(N -2)“)和”7号码“,以及有多少指示只是为了支持这件事。你可能会不同意,但我会说cca。 50%是“支持cruft”,大部分是直接纸 - >代码重写。

学习大会时记住这一点,确保你有你想要达到的公式层次什么第一思路很清晰,然后尝试做 ...只会增加支持代码在绝对必要的。不要仅仅写一些随机的指令,因为它看起来像个好主意,或者你之前写过这样的指令。指令要么“做某件你想要的事”,要么将其切除。在评论


编辑:

mov esi,OFFSET numbers店符号 “号” 的地址为esi。如果您将numbers声明为​​或DWORD,则地址指向分配的内存的第一个位置(第一个字节),这并不重要。

字节/双字/ dup对于分配足够的总空间很重要,但不会影响地址本身(“符号”)。

mov [aaa],vvv将值“vvv”存储到地址“aaa”的存储器中(请查看指令说明以查看可能的组合)。

因此mov [esi],edx之后mov esi,OFFSET numbers之后将存储每个值在“数字[0]”。在调试器中,那个esi每次被那个mov esi,OFFSET numbers复位。

请不要使用夸克语法mov numbers,edx,其存储值装入只在MASM“数字”阵列(和TASM当模拟MASM怪异模式),在适当的英特尔语法指针/地址的[]信号解除引用的使用,因此在读取源代码时很容易判断指令是仅以寄存器/立即数运行还是访问存储器。 (lea reg,[address]是例外,即不访问内存,只计算地址)。在NASM中,mov numbers,edx根本无法编译,而mov edx,numbers不会加载数组中的第一个值,而是地址本身(在MASM/TASM中,您必须在符号之前写入OFFSET)。

所以

“做的代码存储的数字数组中的EAX寄存器的值?”

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

+0

我编辑我的代码如下:(?) – ISM34

+0

ExitProcess的原型 。数据 号码DWORD 10 DUP .CODE 主PROC \t MOV EBX,0 \t MOV EDX,1个 \t MOV号码,EDX \t MOV ECX,10 \t MOV ESI,4 L1: \t MOV EAX,EBX \t添加EAX,EDX \t MOV ESI,偏置号 \t MOV [ESI],EDX \t MOV EBX,EDX \t MOV EDX,EAX \t添加ESI,4 \t环路L1 \t呼叫了ExitProcess 主ENDP END – ISM34

+0

当我单步执行代码,eax寄存器将显示Fibonacci序列值:1,2,3,5,8,13等。但是,代码是否将eax寄存器值存储在numbers数组中?如果不是,我该怎么做。 – ISM34