Проблема с пониманием того, как получить доступ к памяти из стека

Я пытаюсь научить себя сборке, и у меня возникли трудности с взаимодействием между стеком и доступом к нему. Я использую 64-битную систему x86 и выполнял простую программу, которая помещает 5 и 2 в стек (в указанном порядке), а затем вызывает функцию. Таким образом, если размер слова составляет 2 байта, я должен получить 2, выполнив учетную запись [esp+2] для обратного адреса. Однако я получаю 0, потому что, когда я использую edg и пошагово, значение (путем перемещения его в регистр) равно 00000002000000, поэтому я могу получить к нему доступ с помощью [esp+8], а затем 5 с помощью [esp+16], однако это будет означать, что размер слова равен 4? Значит ли это, что размер слова зависит от разрядности системы? А как насчет даже просто используемого регистра? Вместо этого это потому, что размер каждого сегмента стека составляет 8 байтов в 64-битной системе?

«Слово» всегда составляет 2 байта в терминологии x86. Но это не «размер слова» или ширина регистра. «размер слова» не является полезной концепцией для x86-64.; он изначально поддерживает размеры операндов 1, 2, 4 и 8 байтов (и 16, 32 и 64 с SSE, AVX и AVX512 в векторных регистрах). Реальные шины данных шире, чем целочисленные регистры и т.д. и т.п.

Peter Cordes 31.05.2019 03:55

@ Дэвид С. Рэнкин, это два совершенно разных вопроса. Речь идет не о передаче параметров в функцию, а о разных размерах регистров и стека для каждого сегмента от машины к машине...

Ford Smith 31.05.2019 05:49

Вот почему он указан как «Возможный дубликат», и голосование «Закрыть» не проводилось. Он явно обращается к соглашению о вызовах x86_64, например. RDI, RSI, RDX, RCX, R8, and R9, etc... что относится к вашему "I am using a x86 64 bit system and was doing a simple program that pushes 5 and 2 into the stack (in that order) and then call a function." Это не то, как значения передаются на x86 64.

David C. Rankin 31.05.2019 05:56
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Instead is it because the size for each segment of the stack is 8 bytes on a 64 bit system?

да.

Когда вы нажимаете эти вещи, а затем вызываете функцию, это ваш стек:

+-----------------+
|        5        | RSP+0x10
+-----------------+
|        2        | RSP+0x08
+-----------------+
|   Return Addr   | RSP+0x00
+-----------------+

Точно так же в 32-битной системе вы смотрите на это для своего стека:

+-----------------+
|        5        | ESP+0x08
+-----------------+
|        2        | ESP+0x04
+-----------------+
|   Return Addr   | ESP+0x00
+-----------------+

Кстати, помните, что 64-битные регистры начинаются с R (RSP, RAX и т. д.). Кроме того, в зависимости от вашей операционной системы вы, вероятно, будете неправильно передавать параметры через стек. 64-битные системы используют регистры для первых N параметров, а затем стек. Регистры различаются в зависимости от того, передаете ли вы целые числа/указатели или числа с плавающей запятой. Для ваших целей с SystemV первые 6 передаются через RDI, RSI, RDX, RCX, R8 и R9 (именно в таком порядке). 64-разрядная версия Windows использует RCX, RDX, R8 и R9 для первых 4 (именно в таком порядке). Это не важно сейчас, пока вы учитесь, но это будет становиться все более важным, когда вы начнете вызывать другие модули/API ОС.

Я использую линукс. Использует ли это первый порядок, о котором вы говорили?

Ford Smith 31.05.2019 04:20

Да, @FordSmith.

Simon Whitehead 31.05.2019 04:22

Другие вопросы по теме