2012-04-22 2 views
26

Учитывая этот кусок кода:Базовый указатель и указатель стека

 swap: 

      push ebp ; back up the base pointer, 
      mov ebp, esp 
      ; push the context of the registers on the stack 

      push eax 
      push ebx 
      push ecx 
      push edx 

      mov eax, [ebp+8] ; address of the first parameter 
      mov ebx, [ebp+12] ; address of the second parameter 
      mov dl, [eax] 
      mov cl, [ebx] 

      mov [eax], cl 

      mov [ebx], dl 

      ; restore the context of the registers from the stack 

      pop edx 
      pop ecx 
      pop ebx 
      pop eax 
      ; restore the ebp 
      pop ebp 
      ret 

(Это просто метод Ранее мы протолкнул первый и второй параметр в стеке.).

Мой вопрос: почему мы добавляем 8 к базовому указателю, чтобы перейти к адресу первого параметра, а затем 12?

Я получаю тот факт, что они являются dword, поэтому каждый из них составляет 4 байта. От ebp + 8 до ebp + 12 это делает смысл делать. Но почему первый из них - ebp + 8? Поскольку, если ESP указывает на верхнюю часть стека, mov ebp, esp означает, что EBP указывает на верхнюю часть стека. Затем мы нажимаем 4 значения в стеке: eax, ebx, ecx и edx. Почему EBP + 8 указывает на первый параметр?

ответ

39

Когда функция вызывается, стек выглядит следующим образом:

+-------------+ 
| Parameter 2 | 
+-------------+ 
| Parameter 1 | 
+-------------+ 
| Return Addr | <-- esp 
+-------------+  

затем после того, как "кадр стека" устанавливается:

+-------------+ 
| Parameter 2 | <-- [ebp + 12] 
+-------------+ 
| Parameter 1 | <-- [ebp + 8] 
+-------------+ 
| Return Addr | 
+-------------+  
| saved ebp | <-- ebp 
+-------------+ <-- esp 

Теперь контекст сохраняется:

+-------------+ 
| Parameter 2 | <-- [ebp + 12] 
+-------------+ 
| Parameter 1 | <-- [ebp + 8] 
+-------------+ 
| Return Addr | 
+-------------+  
| saved ebp | <-- ebp 
+-------------+ 
| saved eax | 
+-------------+  
| saved ebx | 
+-------------+  
| saved ecx | 
+-------------+  
| saved edx | <-- esp 
+-------------+  

Не забывайте, что на многих системах стек растет вниз (и это определенно верно для семейства x86), поэтому вершина стека будет иметь самый низкий адрес памяти.

+0

+1 - Простой, чистый и информативный. – Cyclonecode

+0

Wow довольно чистый! Спасибо, это было очень полезно! Я предполагаю, что ключевым моментом было то, что Стек стекает вниз! Хорошо знать ! Вы сделали мой день. – yhcowboy

5

Потому что в стеке есть еще два предмета; предыдущий ebp, который вы нажимаете в начале этой подпрограммы, и адрес возврата, который помещается в стек вызовом подпрограммы.

+0

Я бы никогда не подумал, что адрес возврата был нажат на стек! большое спасибо – yhcowboy

Смежные вопросы