2012-04-14 2 views
5

Почему у нас есть команды, такие как push и pop?Neccessity push и pop операндов на процессорах

Из того, что я понимаю pop и push в основном такие же, как делают (mov затем add) и (sub затем mov) на esp соответственно.


Например, не будет:

pushl %eax 

эквивалентно:

subl $4, %esp 
movl %eax, (%esp-4) 

, пожалуйста, поправьте меня, если доступ стека не (%esp-4), я все еще учусь сборки


Единственное истинное преимущество, которое я вижу, заключается в том, что если обе операции одновременно дают некоторое преимущество; однако я не понимаю, как это возможно.

+1

Это экономит место, а x86 на самом деле является дизайном CISC, поэтому почему бы и нет. – harold

+0

@harold он не предоставляет никакой дополнительной функции, поэтому нет. ЦП по-прежнему тратит время на обе операции. – Hawken

+0

Да .. но это дизайн CISC, поэтому он был разработан, чтобы облегчить работу программистов по сборке, предоставив инструкции, которые «делают многое». См. Также: 'leave',' enter', 'rep movsb' и т. Д. И это действительно экономит много места в байтах. – harold

ответ

8

Но тогда нет никакой причины для инструкции CALL. В конце концов, вы можете имитировать вызов:

sub esp,4 
mov [esp-4], offset return_address 
jmp myproc 

И нет никакой необходимости в RET инструкции, либо, потому что вы можете имитировать его:

mov eax,[esp] 
add esp,4 
jmp [eax] 

Если вы посмотрите достаточно трудно, вы» Вы найдете множество инструкций, которые можно моделировать, комбинируя другие инструкции. В чем смысл?

Ответ на эти вопросы задается в длинной истории семейства процессоров x86 и в процессорах, которые были перед ним. Дизайнеры изучили, как программисты используют процессоры и создали набор команд, который был эффективен с точки зрения скорости выполнения и использования памяти.

В конце 70-х годов в 64 килобайтах было много оперативной памяти, а оперативная память была намного медленнее. Каждый байт инструкции был драгоценным, и было огромное количество накладных расходов, просто извлекая инструкцию из памяти. Это было не редкость, когда команда fetch занимала больше времени, чем выполнение. Таким образом, было огромное усиление производительности, которое можно было бы кодировать, используя как можно меньше байтов инструкций.

ОЗУ по-прежнему невероятно медленное по сравнению с тактовыми частотами процессора, поэтому по-прежнему можно получить усиление путем кодирования как можно меньше байтов инструкций. Это правда, что большой кеш процессора очень помогает, так же как и логика предсказания ветвей и prefetch, но каждый байт, переданный из ОЗУ в кеш процессора, по-прежнему дорогой. Платит быть экономным с кодировками инструкций.

о вызове процедур:

Стандартный способ вызова процедуры на ассемблере, чтобы раздвинуть параметры, а затем call процедура.Например, это проходит два типа DWORD значения:

push eax 
push ebx 
call proc ; pushes the return address and jumps to proc 
... 

proc: 
    ; at this point, [esp] contains the return address 

ret инструкция POPS обратный адрес в указатель команд.

Кто-то должен, конечно, очистить стопку. Вызывающий может очистить стек, увеличивая указатель стека. Или вызываемая процедура может очистить стек, используя ret 8, который вытолкнет адрес возврата и увеличит указатель стека.

Для получения дополнительной информации о соглашениях о вызовах см. http://www.delorie.com/djgpp/doc/ug/asm/calling.html.

+0

Я думал, что перед вызовом требуется сублимировать $ 4,% esp' или, по крайней мере, до прерывания; Кроме того, почему '% esp' имеет обратный адрес в вашем примере? – Hawken

+0

@ Хокен: Вы должны куда-то поместить обратный адрес. –

+0

но почему обратный адрес у указателя стека? Предполагается ли, что вы очистили стек, который вы использовали для вызываемой функции? – Hawken

1

1 opcode> 2 кода операций, по крайней мере, когда вы пытаетесь уменьшить использование ЦП.

+0

Насколько я понимаю, это экономит память на части исполняемого файла, но обе операции все равно должны выполняться. Возможно, это то, что вдохновило архитектуру RISC? – Hawken

+2

Хм, возможно, это вдохновило * кончится * на архитектуры RISC. –

+0

@hanspassant почему? RISC более предсказуем для каждой инструкции, CISC, похоже, ничего не делает, кроме как сделать «ярлык», который по-прежнему занимает одинаковое количество времени для выполнения (не так много ярлыка). Из того, что я читал о CISC, он медленнее во многих сценариях из-за этих ярлыков. Если я правильно понял что-то вроде 'addl% eax,% ebx', будет тратить время на проверку, если'% eax' и '% ebx' являются адресами памяти перед запуском' addl', потому что он должен поддерживать использование адреса памяти вместо регистров , – Hawken

2

Ну. Если у вас есть две инструкции, они, вероятно, используют больше места. Для этого требуется cpu для передачи большего количества данных. И это занимает больше времени. Для двух отдельных инструкций обычно требуется больше ресурсов процессора. Даже если cpu распараллеливает их, есть больше работы для fetcher, decoder ... Если вы попытаетесь удалить все, кроме абсолютно необходимых инструкций, вы получите машину для тренировки. Окончательный risc, но не очень эффективный на практике.

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

  • Нет связанных вопросов^_^