2010-11-04 6 views
7

Я читаю «Компьютерные системы: перспектива программиста», глава 3 объясняет, что инструкция, и объяснение в книге смущает меня.mov инструкции и регистры - путаница!

дают функцию (страница 142 1 издание) Код

int exchange(int *xp, int y) 
{ 
    int x = *xp; 
    *xp = y; 
    return x; 
} 

Ассамблея сама функция

movl 8(%ebp), %eax //Get xp 
movl 12(%ebp), %edx //Get y 
movl (%eax), %ecx //Get x at *xp 
movl %edx, (%eax) //Store y at *xp 
movl %ecx, %eax  //Set x as return value 

Что меня смущает, это то, что будет храниться, и где
Вот как я это понимаю:

movl 8(%ebp), %eax //Get xp 

Процессор перемещается +8 байт до стека (от указателя кадра %ebp), принимает значение, хранящееся в этом месте, и сохраняет это значение в регистре %eax (в упор - сохраняет значение, а не адрес)

Я прав? Спасибо!

ответ

9

Да, это звучит, как вы получили это право. IMHO, AT & T 8(%ebp) синтаксис менее интуитивно понятен, чем Intel [ebp+8], что более понятно. Скобки показывают, что вы используете значение по адресу в регистре, а число - это смещение от того адреса, который вы действительно хотите.

+0

ОЧЕНЬ верно ...... – ruslik

+1

Итак, поскольку '% ebp' хранит указатель, мы используем круглые скобки вокруг его имени, чтобы указать, что мы получаем значение, сохраненное + 8байт от'% ebp'. В этом случае '8 (% ebp)' содержит указатель '* xp'. Позже в строке 'movl (% eax),% ecx' мы разыгрываем' xp' так же, как в первой строке кода сборки – newprint

+0

Теперь все выпрямляется. Скорбь стала источником смятения! Благодаря ! – newprint

2

Да, это с помощью AT & T синтаксис, который имеет вид:

instruction  source, dest 

Intel сборки является the opposite order.

Вы также правы насчет 8(%ebp), перемещаясь за 8 байт от указателя кадра. Причина, по которой он перемещает 8 байтов, в частности, заключается в том, что параметры вставляются в стек в обратном порядке («справа» на «левый» при просмотре типичного вызова функции). Таким образом, сначала был нажат y, затем xp и, наконец, обратный адрес вызывающей функции (поэтому вы перемещаете 8 байтов, а не 4).

1

Вам нужно понять, что представляет собой стек стека. Узнайте, что именно push и pop инструкция делать. До этого кода там был

push y_val 
    push xp_ptr 
    call exchange 
.cont  
... 
.exchange 
    push ebp 
    mov ebp, esp 
// .. rest of code 
// stack frame: 
    old_ebp_val ; [ebp] points here 
    .cont  ; [ebp + 4] 
    xp_ptr  ; [ebp + 8] 
    y_val 
+0

Мой вопрос не о стеке, даже если речь идет о стеке. Речь идет о значениях, хранящихся в регистре и памяти – newprint

+1

@user Попробуйте использовать RTTI. Всегда отслеживайте типы значений. – ruslik