что на самом деле означает размер регистров и стека в сборке x86

assembly x86

346 просмотра

1 ответ

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

в сборке x86 у нас разные регистры, каждый регистр имеет определенный размер, пример

EAX: 32 бита

Q1- Ну, что на самом деле означает 32бит? это значит, что я могу хранить только значение размером 32 бита?

Если да

Q2 - Если у меня есть очень длинная строка, как я могу переместить эту строку в мой регистр?

Q3 - я хочу точно знать, когда я должен нажать и выскочить из стека?

Q4 Я могу хранить свои значения в моих регистрах без стека. Почему у нас есть стек? решить какую проблему?

если мы возьмем пример, вот мой код C:

#include<stdio.h>

main() 
{
    printf("Hello World");

}

Здесь мы передаем Hello world функции printf, и я могу передать все, что угодно, большое или маленькое, независимо от того, если я перевожу этот код в сборку, сначала я должен переместить аргументы системного вызова в регистры, а затем вызвать системный вызов и затем int 0x80. как насчет того, если у меня будет привет, у меня есть параграф?

Q5 - также, когда я перемещаю какие-либо данные в регистры, как я могу выбрать, какой регистр мне следует перемещать в него данные?

Благодарю .

Автор: Mr.Mark Источник Размещён: 08.11.2019 11:30

Ответы (1)


3 плюса

Решение

Регистрирует номера магазинов. Вот и все. Это все, что они делают. Именно как вы, как программист, используете и интерпретируете эти цифры, что заставляет программу работать.

  • Каждый регистр имеет размер 8, 16, 32 или 64 бита. Они могут хранить либо подписанные или неподписанные числа - то есть, является ли их старший бит интерпретируется как знаковый бит, или просто как часть числа. Обратите внимание, что эти числа могут быть адресом переменной в памяти - тогда подпись не имеет значения.

  • Вы можете добавлять, вычитать или делать много других вещей с числами.
    Поместите один в один регистр, другой в другой, используйте инструкцию ADDили SUB, и вы получите результат:

            MOV  EAX, 0x12345678
            MOV  EBX, 0x12345677
            SUB  EAX, EBX        ; EAX now holds the value 1
    
  • Вы можете указать на значения в памяти. Сохраните адрес переменной в регистре, и вы можете читать и записывать эти значения:

            .DATA
    xValue  DD   42       ; Save xValue here
    
            .CODE
            MOV  EAX, [xValue]         ; Get the current xValue into EAX
            INC  EAX                   ; Add one to it
            MOV  [xValue], EAX         ; Save it back
    
            INC  [xValue]              ; One line to do the above three
    
            MOV  EBX, OFFSET xValue    ; Point to xValue with EBX
            MOV  EAX, [EBX]            ; Get the current value
            INC  EAX                   ; Add one to it
            MOV  [EBX], EAX            ; Save it back
    
            INC DWORD PTR [EBX]        ; One line to do the above three
    
  • Как вы передаете строки?
    Вы не Вы передаете адрес памяти строки, и принимающая функция просто знает, что значение в регистре является адресом строки в памяти.

  • Почему вы PUSHи POPиз стека?

    • Существует только ограниченное количество регистров, поэтому для выполнения процессов, имеющих много разных значений, вам нужно хранить некоторые в памяти, обмениваясь значениями в регистрах и из них, чтобы работать с ними.
    • Вы можете использовать зарезервированные области памяти для каждой переменной; или вы можете временно сохранить значения в стеке, а не резервировать для них определенные места в памяти.
    • Обратите внимание, что если у вас есть рекурсивная функция, зарезервированные области памяти не будут работать - каждый раз, когда для рекурсии требуется новая память для следующей итерации. Стек идеально подходит для этого.
    • Некоторые функции ожидают, что их параметры будут храниться в стеке, а не в глобальных переменных.
  • Как вы знаете, какой регистр использовать?
    По-разному:

    • Если вы пишете код, вы можете использовать любые регистры, которые вам нравятся - кроме SP/ ESP/ RSP, который зарезервирован для указания на стек!
      • Есть несколько архитектурных соглашений:
        • Если вы собираетесь использовать инструкции REPили LOOP, то вам нужно использовать CX/ ECX/ RCXдля хранения счетчика;
        • Если вы собираетесь использовать LODS, STOS, CMPSи MOVSинструкции, то вы должны использовать AL/ AX/ EAX/ RAX, SI/ ESI/ RSIи / или DI/ EDI/ RDI.
      • Есть некоторые исторические соглашения, но они больше не нужны в 32- и 64-битном программировании:
        • BX, SI, DIИ BPбыли единственными регистрами , которые могут индексировать памяти, так это то, что они были использованы для;
    • Если вы не написали код, который вызываете, он должен указать (или использовать общий стандарт), какие регистры содержат какие параметры и какие регистры он использует для возвращаемого значения.
Автор: John Burger Размещён: 21.08.2016 03:41
Вопросы из категории :
32x32