Как это число представляется в ассемблере?

Я пытаюсь проанализировать код сборки для функции

double test_class::Operators
double test_class::Operators_2_12_addtion_07(double input) {
   0:   3d 20 00 00     lis     r9,0
   4:   c0 09 00 00     lfs     f0,0(r9)
      double a = input + 5;

    /*Branch unconditional return*/
    return a;

}
   8:   fc 21 00 2a     fadd    f1,f1,f0
   c:   4e 80 00 20     blr
12_addtion_07(double input) { /*add input with constant value 5*/ double a = input + 5; /*Branch unconditional return*/ return a; }

вот вывод сборки для кода:

double test_class::Operators_2_12_addtion_07(double input) {
   0:   3d 20 00 00     lis     r9,0
   4:   c0 09 00 00     lfs     f0,0(r9)
      double a = input + 5;

    /*Branch unconditional return*/
    return a;

}
   8:   fc 21 00 2a     fadd    f1,f1,f0
   c:   4e 80 00 20     blr

В коде я добавляю постоянное значение 5 к входному параметру, передаваемому через функцию. Инструкция указанная в сборке для инструкции такая:

0:  3d 20 00 00     lis     r9,0
4:  c0 09 00 00     lfs     f0,0(r9) 

Может ли кто-нибудь помочь мне понять, как значение 5 представлено в сборке.


person Anu    schedule 31.03.2016    source источник
comment
Нужна подробная информация о коде — это бесполезный заголовок вопроса. Пожалуйста, отредактируйте, чтобы было более понятно, о чем вы спрашиваете или какую проблему пытаетесь решить таким образом, чтобы что-то значит для будущих читателей, которые найдут его в результатах поиска. Power PC не нужен; эта информация доступна в теге, который вы указали для своего поста. Спасибо.   -  person Ken White    schedule 01.04.2016
comment
Я предполагаю, что вы использовали objdump, убедитесь, что вы передали опцию -r, чтобы увидеть записи о перемещении. Я предполагаю, что константа 5 была помещена в память, и доступ к ней осуществляется косвенно через r9. Два нуля, вероятно, имеют записи о перемещении по адресу константы.   -  person Jester    schedule 01.04.2016
comment
en.wikipedia.org/wiki/Double-precision_format_floating-point   -  person old_timer    schedule 01.04.2016


Ответы (1)


TL;DR

Послушайте комментарий Шутки.


Переезд

Когда компилятор компилирует единицу кода, обычно предполагается, что его код начинается с адреса 0, поэтому он генерирует объектные файлы с адресами, близкими к 0 (если только PIC).

Когда компоновщик связывает объектные файлы, он обычно размещает каждый раздел кода один за другим, поэтому он должен «сдвигать» адреса разделов, следующих за первым.

Когда программа загружена, ее начальный адрес может быть выбранным случайным образом, поэтому загруженный должен "сдвинуться" все адреса еще раз.

Это называется перемещением, оно может быть выполнено различными способами и подразумевает, что сохраненные адреса в объектном/двоичном файле обычно равны нулю или относительно нуля.

Загрузка адреса PowerPC

Как это часто бывает на компьютерах RISC, загрузка константы ширины регистра (как адреса) занимает два инструкций.
Одна для старших битов и одна для младших.
В PowerPC это достигается с помощью пары

lis r1, HIGH16         ;Move HIGH16<<16 into r1
ori r1, LOW16          ;r1 = HIGH16<<16 | LOW16

Если адрес используется для загрузки каких-либо данных, вторая инструкция может быть «вплавлена» в загрузку, используя смещение

lis r1, HIGH16         ;Move HIGH16<<16 into r1
lwz r2, LOW16(r1)      ;r2 = mem[HIGH16<<16 + LOW16]

Соглашение о вызовах PowerPC (часть)

При вызове функции, использующей числа с плавающей запятой, входные данные параметры в регистры f1-f8.
Возвращаемые значения находятся в f1.
f0 является изменяемым регистром.

Объединяем все это

Не существует инструкций, которые загружают числа с плавающей запятой немедленно, поэтому они должны быть расположены в памяти. Я не знаю, какой формат с плавающей запятой использует PowerPC, я предполагаю, что IEEE754.
В этом если число 5 представлено как +1.01x22, то как одиночное точность равна

  S  Exp (127+2)  Significand (Implicit 1)
+---+-----------+-------------------------+
| 1 | 1000 0001 | 010 0000 0000 0000 0000 |
+---+-----------+-------------------------+

or 40a00000h.

Вы можете поэкспериментировать с плавающей запятой здесь.

; f1 = input


;This load a float at address 0 (not yet relocated) into f0
;Such float is the literal 5.
;The zeros are actually the upper and lower part of the literal address
;(that is not relocated)
lis     r9, 0
lfs     f0, 0(r9)  

;f1 = input
;f0 = 5
fadd    f1,f1,f0

;f1 = input + 5
;f0 = 5
blr
person Margaret Bloom    schedule 01.04.2016
comment
Большое спасибо за твою помощь - person Anu; 01.04.2016