2014-10-17 3 views
0

Я новый ученик, и я не хорошо пишу по-английски. Я прочитал из многих источников, что для доступа к локальной переменной в процедуре первый локальный доступ осуществляется с использованием [ebp-4]. Я делаю эту программу для отображения EAX, и только одна информация (string) локальная. Что случилось, [ebp-4] не работал. Я перешел на [ebp-8], и он работает. Почему так?Доступ к локальной строке через EBP

 mov  eax,0x0ffffc345 
     push eax 
     call Disp_EAX 
     call exit 

Disp_EAX: 
     push ebp 
     mov  ebp,esp 
     sub  esp,12 ;for string to display EAX 
     cld 
     lea  edi,[ebp-8] ;why can't [ebp-4]? 
     mov  esi,8 
     mov  edx,[ebp+8] 
     mov  eax,0 
extract: 
     shld eax,edx,4 
     add  al,0x30 
     cmp  al,0x39 
     jle  continue 
     add  eax,7 
continue: 
     stosb 
     dec  esi 
     cmp  esi,0 
     je  done 
     rol  edx,4 
     xor  al,al 
     jmp  extract 
done: 
     mov  eax,0 
     stosb 
     lea  esi,[ebp-8] 
     cinvoke printf,esi 
     add  esp,12 
     mov  esp,ebp 
     pop  ebp 
     ret 

Надеюсь, вы можете мне помочь.

Дополнение: Если я использовал [ebp-4], мой цикл программ непрерывно, но отображается правильно. Я действительно смущен.

ответ

0

Стек растет на x86. Если вы установили стандартный стек стека, ebp указывает на один конец конца ваших локальных переменных, которые начинаются с текущего значения esp. Таким образом, у вас есть ebp - esp байт местных жителей.

Вы выделяете 12 байтов, используя sub esp, 12, поэтому адрес этого блока равен ebp-12. В цикле вы используете 8 байтов этого блока. Если вы начинаете с ebp-8, вы пишете ebp-8 через ebp-1, и все в порядке, то есть внутри вашего квартала местных жителей. Если вы используете ebp-4, вы пишете от ebp-4 до ebp+3, что плохо, так как последние 4 байта не находятся в вашем блоке, выделенном для локальных переменных. Вы перезапишите сохраненный ebp в стек, который был помещен туда push ebp, и это вызовет непредсказуемые проблемы.

+0

Спасибо за хорошее объяснение Шут. Таким образом, доступ к локальным данным не всегда начинается с [ebp-4]. Это было очень запутанное чтение из некоторых веб-материалов. Это все говорит. или это просто я понял, что это совершенно неправильно. – kent

+0

Локальные данные заканчиваются на 'ebp'. Первый локальный, если это целое число в 4 байта, находится в 'ebp-4', а второй - в' ebp-8', так как стек растет. Локали занимают область памяти, заканчивающуюся на 'ebp', начиная с' esp', которая представляет собой некоторое отрицательное смещение (размер всех локальных пользователей) из 'ebp'. – Jester

+0

Да. я узнаю, что большинство ссылок предполагают, что локальные данные должны быть 4 байта. очень редко я нахожу ee, я нахожу примеры, используя строку большего размера. Я думаю, что это вызывает путаницу. 4 байта - это стандарт де-факто для примеров стека. еще раз спасибо – kent