2017-11-26 1 views
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 

내가 재귀로 인해 엉망이되고 어딘가에 스택에 값을 저장에서 실수를 만들고있어 의심의 노드의 합을 찾기 위해 Y86 코드를 쓰고 있어요. 미안하지만 나는이 사실을 잘 이해하지 못하고 싶지 않다. 어떤 도움을 주셔서 감사합니다. 감사!

마침내 RAX 나를 포기해야합니까 : 0x0000cba 내가지고 있어요 당신은 부분적으로 재귀 호출의 결과로 현재 노드에서 저장된 값을 덮어 쓸 것 0x0000040

enter image description here

+0

문제에 대해 설명해주십시오. 그것은 무엇을하고 있으며, 어떻게 잘못하고, 어떤 일이 일어나게되는지 등등. 이것은 우리가 무슨 일이 일어나고 있는지를 이해하고 문제를 찾는데 도움이 될 것입니다. –

+0

@SamKuhmonen이 도움이됩니까? –

+1

'$ 18'은 아마'$ 0x18'로되어 있기 때문에 스택은 16 바이트 정렬을 유지합니다. ('0x10'). 십진수 '18'은 예약 할 스택 공간이 매우 이상하지만 16 진수 '0x18'은 의미가 있습니다. –

답변

1

입니다 . 기록 된 값이 8 바이트 비록 두 개의 저장 위치는 2 바이트가 떨어져있는 것을

*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 

참고 : 나는 아래의 관련 라인에 별표를 추가했습니다. 인텔의 리틀 엔디안 저장 협약을 감안할 때, 다음과 같이 정렬됩니다 기록하는 열을

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)     

불행하게도 (ans는 재귀 호출에서 답을 나타내는으로) 주어진 재귀 깊이에서 발생하는 세 가지 쓰기의 위치를 ​​제공하는 경우, 이것만으로도 0x40이 생성되지 않아야하므로 다른 점이 있습니다.