[英]How to decompile this x87 assembly calculation?
我正在反轉的程序在浮點數和8字節整數之間進行簡單的乘法運算:
section .data
va: dt 1.4426950408889634074
vb: dd 0x42424242
dd 0x41414141
section .text
global main
main:
fld tword[va]
fmul qword[vb]
ret
gdb下的結果:
Breakpoint 1, 0x08048360 in main ()
(gdb) x/i $eip
0x8048360 <main>: fld TBYTE PTR ds:0x804953c
0x8048366 <main+6>: fmul QWORD PTR ds:0x8049546
0x804836c <main+12>: ret
(gdb) x/gx 0x8049546
0x8049546 <vb>: 0x4141414142424242
(gdb) si
0x08048366 in main ()
0x0804836c in main ()
(gdb) info float
=>R7: Valid 0x4014c726039c95268dc4 +3262848.902912714389
我正在嘗試在C(相同的32位環境)中重新創建此程序:
#include <stdio.h>
int main() {
unsigned long long vb = 0x4141414142424242LL;
float r, va = 1.4426950408889634074F;
r = va * vb;
printf("%f\n", r);
}
...但我得到了非常不同的結果:
$ ./test
6783712964982603776.000000
我在C程序中做錯了什么?
在asm代碼中,你實際上是將兩個double
與fmul
指令相乘,而不是float
和int
。 在C中做類似的事情:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main()
{
uint64_t vbi = 0x4141414142424242ULL; // hex representation of double
double r, vb, va = 1.4426950408889634074;
memcpy(&vb, &vbi, sizeof(vb)); // copy hex to double
r = va * vb;
printf("va = %f, vb = %f, r = %f\n", va, vb, r);
return 0;
}
結果= va = 1.442695, vb = 2261634.517647, r = 3262848.902913
。
這個匯編程序代碼沒有按照您的想法執行:
main:
fld tword[va]
fmul qword[vb]
ret
你建議浮點數和8字節整數之間的簡單乘法 。 這實際上是將10字節擴展雙浮點值乘以由0x4141414142424242表示的8字節雙精度(不是8字節整數)。 0x4141414142424242被代碼視為8字節雙浮點值的位,而不是轉換為雙浮點值的8字節整數。
您認為發生的事情的代碼可能看起來像:
main:
fild qword[vb] ; Convert 64-bit integer to an extended precision double in st0
fld tword[va] ; st(0)=>st(1) st(0) = 10-byte float(va)
fmulp ; Multiply st(0) and st(1). Result in st(0).
這只是清除了你對匯編代碼的誤解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.