なぜこのシンプルなプログラムが非常に多くのキャラクターを出力しているのですか?

StackOverflow https://stackoverflow.com/questions/3693692

  •  02-10-2019
  •  | 
  •  

質問

これが私のものです 短い アセンブリプログラム:

; 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

私は一体何をしているのですか?コードは2つの引数を押しています printf() そしてそれを呼びます。複雑なものはありません。


アップデート: 私はこれを修正したと思って少し時期尚早でした。コードを更新しました。

役に立ちましたか?

解決

指示 push f_0 メモリの5.5ではなく、スタック上のF_0のアドレスをプッシュするため、PrintFルーチンはアドレスを取得し、保存されたEBP(スタックの次の4バイト)を取り、ビットをダブルとして解釈して印刷します。ご覧のとおり、それは非常に多数であることが判明しました。

から8バイトをロードする必要があります f_0 そしてそれらをプッシュします。何かのようなもの

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

編集

FP64値は8バイトであるため、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に変換し、スタックに保存します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top