0

注意:这是一个类。我只是想了解 rsp 和 rbp 是如何工作的,这样我就可以了解我的代码的哪一部分被搞砸了。对不起,我是新手。谢谢你的帮助。

所以我正在编写 Y86 代码来查找链表的节点总和

        .pos 0
    init:   irmovq  Stack, %rsp     # Set up stack pointer
    rrmovq  %rsp,%rbp       # Set up base pointer
    irmovq  ele1,%rdi
    irmovq  $18, %r8        #Note 1 : unsure of what this should be
    call    rsum_list        # Execute main program
    halt                    # Terminate program


  # Sample linked list
    .align 8
  ele1:   .quad 0x00
    .quad ele2
  ele2:   .quad 0x0b0
    .quad ele3
  ele3:   .quad 0xc00
    .quad 0

        # int sum_list(list_ptr ls)
  rsum_list:  pushq   %rbp
        rrmovq  %rsp,%rbp
        xorq    %rax,%rax       # val = 0
        subq %r8, %rsp              #subtract constant from rsp , not sure why we need to do this -> saw this in x86 code
        rmmovq %rdi, -18(%rbp)      #move ls to -18(%rbp)
        andq %rdi, %rdi             #check if 0   
        je End
        mrmovq -18(%rbp), %rax
        mrmovq (%rax), %rax            #rax gets ls->val
        rmmovq %rax, -10(%rbp)         #the val obtained is stored in -10(%rbp)
        mrmovq -18(%rbp), %rax         #rax becomes ls again
        mrmovq 8(%rax), %rax          # rax gets ls-> next
        rmmovq %rax, %rdi             #this is copied to rdi for next recursive call
        call rsum_list
        rmmovq %rax, -8(%rbp)          #rax will contain ans from recursive call
        mrmovq -10(%rbp), %rdx       #retrieve ans. of current node from -10(%rbbp) , where we stored it before recursion
        mrmovq -8(%rbp), %rax      
        addq %rdx, %rax           #adding

  End :
       rrmovq %rbp, %rsp
       popq %rbp
       nop                     # makes sure stop in 31 steps
       ret

我怀疑我在将值存储在由于递归而被弄乱的堆栈上时犯了一个错误。对不起,但我真的不明白这一点,也想。任何帮助表示赞赏。谢谢!

它最终应该在 rax 中给我什么:0x0000cba 我得到的是 0x0000040

在此处输入图像描述

4

1 回答 1

1

您似乎用递归调用的结果部分覆盖了当前节点的存储值。我在下面的相关行中添加了星号:

*rmmovq %rax, -10(%rbp)         #the val obtained is stored in -10(%rbp)
 mrmovq -18(%rbp), %rax         #rax becomes ls again
 mrmovq 8(%rax), %rax          # rax gets ls-> next
 rmmovq %rax, %rdi             #this is copied to rdi for next recursive call
 call rsum_list
*rmmovq %rax, -8(%rbp)          #rax will contain ans from recursive call
 mrmovq -10(%rbp), %rdx       #retrieve ans. of current node from -10(%rbbp) , where we stored it before recursion
 mrmovq -8(%rbp), %rax

请注意,虽然写入的值是 8 字节长,但两个存储位置仅相隔 2 个字节。鉴于英特尔的小端存储约定,写入将按如下方式对齐,其中列给出了在给定递归深度发生的三个写入的位置(ans表示来自递归调用的答案)

RBP: 
 -1:                         ans(MSB)     
 -2:                         ans     
 -3:           ls->val(MSB)  ans     
 -4:           ls->val       ans     
 -5:           ls->val       ans     
 -6:           ls->val       ans     
 -7:           ls->val       ans     
 -8:           ls->val       ans(LSB)
 -9:           ls->val     
-10:           ls->val(LSB)     
-11: ls(MSB)                
-12: ls                
-13: ls                
-14: ls                
-15: ls                
-16: ls                
-17: ls                
-18: ls(LSB)                

不幸的是,仅此一项不应该产生您的 0x40,所以还有其他问题。

于 2017-11-26T10:44:18.370 回答