Я пытаюсь научить себя сборке, и у меня возникли трудности с взаимодействием между стеком и доступом к нему. Я использую 64-битную систему x86 и выполнял простую программу, которая помещает 5 и 2 в стек (в указанном порядке), а затем вызывает функцию. Таким образом, если размер слова составляет 2 байта, я должен получить 2, выполнив учетную запись [esp+2] для обратного адреса. Однако я получаю 0, потому что, когда я использую edg и пошагово, значение (путем перемещения его в регистр) равно 00000002000000, поэтому я могу получить к нему доступ с помощью [esp+8], а затем 5 с помощью [esp+16], однако это будет означать, что размер слова равен 4? Значит ли это, что размер слова зависит от разрядности системы? А как насчет даже просто используемого регистра? Вместо этого это потому, что размер каждого сегмента стека составляет 8 байтов в 64-битной системе?
Возможный дубликат Каковы соглашения о вызовах для системных вызовов UNIX и Linux на i386 и x86-64?
@ Дэвид С. Рэнкин, это два совершенно разных вопроса. Речь идет не о передаче параметров в функцию, а о разных размерах регистров и стека для каждого сегмента от машины к машине...
Вот почему он указан как «Возможный дубликат», и голосование «Закрыть» не проводилось. Он явно обращается к соглашению о вызовах 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.
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 ОС.
Я использую линукс. Использует ли это первый порядок, о котором вы говорили?
Да, @FordSmith.
«Слово» всегда составляет 2 байта в терминологии x86. Но это не «размер слова» или ширина регистра. «размер слова» не является полезной концепцией для x86-64.; он изначально поддерживает размеры операндов 1, 2, 4 и 8 байтов (и 16, 32 и 64 с SSE, AVX и AVX512 в векторных регистрах). Реальные шины данных шире, чем целочисленные регистры и т.д. и т.п.