Почему эта простая программа выводит так много символов? - PullRequest
0 голосов
/ 12 сентября 2010

Вот моя короткая программа сборки:

; This code has been generated by the 7Basic
; compiler <http://launchpad.net/7basic>

extern printf

; Initialized data

      SECTION .data
f_0 dd 5.5
printf_f: db "%f",10,0

      SECTION .text

; Code

global main
  main:
push ebp
mov ebp,esp

push dword [f_0]
push printf_f
call printf
add esp,8

mov esp,ebp
pop ebp
mov eax,0
ret

Что программа должна сделать, это напечатать 5.5, но она напечатает:

-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000

Что, черт возьми, я делаю не так? Код помещает два аргумента в printf() и затем вызывает его. Ничего сложного.


Обновление: Я был немного преждевременным, думая, что я это исправил. Я обновил код.

1 Ответ

5 голосов
/ 12 сентября 2010

Инструкция push f_0 помещает в стек адрес f_0, а не 5,5 в памяти, поэтому процедура printf возьмет адрес плюс сохраненный ebp (следующие 4 байта в стеке) и интерпретирует биты.как двойной и распечатать его.Как видите, это очень большое число.

Вам нужно загрузить 8 байтов из f_0 и нажать их.что-то вроде

move eax, f_0
push dword ptr [eax+4]
push dword ptr [eax]

edit

Вам нужно нажать 8 байтов, так как значения fp64 равны 8 байтов.fp64 - это все, что printf знает, как печатать. Фактически, fp64 - это все, что C знает, как передавать функции или работать с ними.Значение fp32 может быть загружено только из памяти и сохранено в памяти, но всегда неявно преобразуется в fp64 (или больше) перед использованием.Если вы хотите загрузить значение fp32, преобразовать его в fp64 и поместить его в стек, вы можете использовать

fld dword ptr [f_0]
sub esp, 8
fstp qword ptr [esp]

Это фактически загружает значение fp32 и преобразует его в fp80 (внутренний формат x87),затем преобразует это значение fp80 в fp64 и сохраняет его в стеке.

...