CSAPP путают с результатами pushtest Практическая задача 4.7 - PullRequest
0 голосов
/ 11 июля 2019

Y86 аналогично x86-64.Почему функция pushtest всегда возвращает ноль?

Как я знаю на x86-64 Push сначала уменьшает регистр ESP, а не записывает.Сначала читается, а затем увеличивается регистр ESP.

    .text
.globl pushtest
pushtest:
    movq    %rsp, %rax
    pushq   %rsp
    popq    %rdx
    subq    %rdx, %rax
    ret

Ответы [ 2 ]

0 голосов
/ 11 июля 2019

Я ссылаюсь Этот ответ «pushq» можно заменить на «subq и movq», «popq» можно заменить на «movq и addq».

Но «PUSH ESP» и «POP ESP» являются особым случаем. Ссылка Этот ответ . Но результат не "0"

pushq% rsp ; толкает значение регистра ESP в том виде, в каком оно существовало до выполнения инструкции.

popq% rsp ; увеличивает указатель стека (ESP) до того, как данные из старой вершины стека будут записаны в место назначения.

pushq% rdx ; Уменьшает указатель стека, а затем сохраняет исходный операнд на вершине стека.

popq% rdx ; Загружает значение из верхней части стека в местоположение, указанное с помощью операнда-получателя (или явного кода операции), а затем увеличивает указатель стека.

rax =
rdx =

0x28 |  0x12  |
0x30 |  0x34  | <--- rsp
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |


movq    %rsp, %rax
rax = 0x30
rdx =

0x28 |  0x12  |
0x30 |  0x34  | <--- rsp
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |


pushq   %rsp ;store, using rsp as the address, then subtract 8 from rsp
rax = 0x30
rdx =

0x28 |  0x12  | <--- rsp
0x30 |  0x30  |
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |


popq    %rdx ;load, using rsp as the address, then add 8 to the rsp
rax = 0x30
rdx = 0x30

0x28 |  0x12  | <--- rsp
0x30 |  0x30  |
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |

subq    %rdx, %rax    ;Return 0
rax = 0x00
rdx = 0x30

0x28 |  0x12  |
0x30 |  0x30  | <--- rsp
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |
0 голосов
/ 11 июля 2019

Во-первых. Вы не должны изменять %rsp (то есть регистр указателя стека) вручную, не делайте movq %rsp, .... %rsp управляется (и должно управляться только) push, pop, call, ret. Проверьте также этот вопрос .

Тогда это всегда %rdx == 0 в конце, потому что:

movq    %rsp, %rax  ; %rsp==%rax
pushq   %rsp        ; top of the stack := %rsp == %rax
popq    %rdx        ; %rdx := top of the stack == %rax
subq    %rdx, %rax  ; %rdx := %rdx - %rax , i.e. %rdx := %rax - %rax == 0
...