Неоптимизированный код всегда сохраняет все переменные C ++ (включая аргументы функций) в их ячейке памяти между операторами, , чтобы значения были доступны для чтения отладчиком и даже , изменения , (И поскольку он не тратил никакого времени на распределение регистров.) Это включает в себя сохранение регистровых аргументов в памяти до первого оператора C ++ функции.
Это синтаксическая сборка Intel, подобная gcc -masm=intel
, поэтому она использует пункт назначения, исходный порядок. (Мы можем определить это, используя PTR, квадратные скобки и отсутствие %
в именах регистров.)
Первые 3 хранилища - это аргументы функции (this, a, b)
, которые были переданы в регистрах RDI, RSI и RDX в соответствии с соглашением о вызовах ABI системы V системы x86-64.
mov QWORD PTR [rbp-8], rdi # this
mov QWORD PTR [rbp-16], rsi # a
mov QWORD PTR [rbp-24], rdx # b
Теперь он загружает this
в rax
и записывает нули в a_
и b_
, потому что вы не использовали правильную инициализацию конструктора. Или, возможно, вы добавили инициализацию к нулю с помощью некоторого кода, который вы здесь не показывали, или нечетного параметра компилятора.
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], 0 # this->a_ = 0
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax+8], 0 # this->b_ = 0
Затем он загружает this
в rax
снова и a
в rdx
, затем записывает this->a_
с rdx
aka a
. То же самое для b
.
Подождите, на самом деле это должна быть сначала запись в b_
, а затем запись в a_
, потому что структуры должны соответствовать объявлению и порядку памяти. Так что [rax+8]
должно быть b_
, а не a_
.
mov rax, QWORD PTR [rbp-8]
mov rdx, QWORD PTR [rbp-16] # reload a
mov QWORD PTR [rax+8], rdx # this->b_ = a
mov rax, QWORD PTR [rbp-8]
mov rdx, QWORD PTR [rbp-24] # reload b
mov QWORD PTR [rax], rdx # this->a_ = b
Таким образом, ваш asm не соответствует источнику C ++ в вашем вопросе.