15.2 通过参数通过浮点数

  1. #include <math.h>
  2. #include <stdio.h>
  3. int main ()
  4. {
  5. printf ("32.01 ^ 1.54 = %lf", pow (32.01,1.54));
  6. return 0;
  7. }

15.2.1 x86

让我们来看看在(msvc2010)中得到的东西

清单15.3 :MSVC 2010

  1. CONST SEGMENT
  2. __real@40400147ae147ae1 DQ 040400147ae147ae1r ; 32.01
  3. __real@3ff8a3d70a3d70a4 DQ 03ff8a3d70a3d70a4r ; 1.54
  4. CONST ENDS
  5. _main PROC
  6. push ebp
  7. mov ebp, esp
  8. sub esp, 8 ; allocate place for the first variable
  9. fld QWORD PTR __real@3ff8a3d70a3d70a4
  10. fstp QWORD PTR [esp]
  11. sub esp, 8 ; allocate place for the second variable
  12. fld QWORD PTR __real@40400147ae147ae1
  13. fstp QWORD PTR [esp]
  14. call _pow
  15. add esp, 8 ; "return back" place of one variable.
  16. ; in local stack here 8 bytes still reserved for us.
  17. ; result now in ST(0)
  18. fstp QWORD PTR [esp] ; move result from ST(0) to local stack for printf()
  19. push OFFSET $SG2651
  20. call _printf
  21. add esp, 12
  22. xor eax, eax
  23. pop ebp
  24. ret 0
  25. _main ENDP

FLD和FSTP读取FPU的栈中的变量。pow()从FPU栈中拿出两个值然后将结果返回到ST(0)寄存器中。printf()函数从本地栈中取出8字节并且将他们翻译为双精度变量。

15.2.2 ARM+Non-optimizing Xcode(LLVM)+thumb-2模式

  1. _main
  2. var_C = -0xC
  3. PUSH {R7,LR}
  4. MOV R7, SP
  5. SUB SP, SP, #4
  6. VLDR D16, =32.01
  7. VMOV R0, R1, D16
  8. VLDR D16, =1.54
  9. VMOV R2, R3, D16
  10. BLX _pow
  11. VMOV D16, R0, R1
  12. MOV R0, 0xFC1 ; "32.01 ^ 1.54 = %lf
  13. "
  14. ADD R0, PC
  15. VMOV R1, R2, D16
  16. BLX _printf
  17. MOVS R1, 0
  18. STR R0, [SP,#0xC+var_C]
  19. MOV R0, R1
  20. ADD SP, SP, #4
  21. POP {R7,PC}
  22. dbl_2F90 DCFD 32.01 ; DATA XREF: _main+6
  23. dbl_2F98 DCFD 1.54 ; DATA XREF: _main+E

就像我以前写的一样,64位的浮点数是成对传递给R系列寄存器的。这样的代码是冗陈的(当然是因为优化选项关掉了),因为,事实上直接从R系列寄存器传递值,不借助D系列寄存器是可能的。

因此我们可以看到,pow 将第一个参数放入R0和R1中,第二个参数放入R2和R3中。函数结果放入R0和R1中。pwn的结果先放入了D16中,然后再放入R1和R2中,然后printf函数将取走这个值。

15.2.3 ARM+非优化模式keil+ARM模式

  1. _main
  2. STMFD SP!, {R4-R6,LR}
  3. LDR R2, =0xA3D70A4 ; y
  4. LDR R3, =0x3FF8A3D7
  5. LDR R0, =0xAE147AE1 ; x
  6. LDR R1, =0x40400147
  7. BL pow
  8. MOV R4, R0
  9. MOV R2, R4
  10. MOV R3, R1
  11. ADR R0, a32_011_54Lf ; "32.01 ^ 1.54 = %lf
  12. "
  13. BL __2printf
  14. MOV R0, #0
  15. LDMFD SP!, {R4-R6,PC}
  16. y DCD 0xA3D70A4 ; DATA XREF: _main+4
  17. dword_520 DCD 0x3FF8A3D7 ; DATA XREF: _main+8
  18. ; double x
  19. x DCD 0xAE147AE1 ; DATA XREF: _main+C
  20. dword_528 DCD 0x40400147 ; DATA XREF: _main+10
  21. a32_011_54Lf DCB "32.01 ^ 1.54 = %lf",0xA,0
  22. ; DATA XREF: _main+24

D系列寄存器在这里不使用,只成对地使用R系列的寄存器