; Demonstrates the proper way to call printf to print floating
; point numbers and also demonstrates scaled index addressing
; mode. NOTE: YOU CAN NOT USE the 16-bit registers, ax, bx, etc
; in any of the complex addressing modes. You get an error "invalid effective address" or
; "ELF format does not support non-32-bit relocations"
; Also included is the state of the FPU registers after each instruction. Pay attention to how
; floating point operations leave data on the stack that the programmer must clean up. I also put
; in the results of store operations printed out using gdb.
global main
extern printf
section .data ;section declaration
; An array of two floating point numbers initialized to 23.25.
myfloatarr times 2 dd 23.25
myfloatstr db 'This number -> %f <- should be 23.25', 10, 0
flt1 dd 12.34
dd 23.45
dd 34.56
dd 45.67
dd 56.78
flt2 dd 0
dd 0
r dd 20.3
anInt dd 17
diameter dd 0
section .text
main:
finit ; initialize the FPU
; Simple example of scaled index addressing mode. in C, this is the same thing as:
; st0 = myfloatarr[ 1 ]; /* assuming you could directly assign something to st0 */
mov ebx, 1
fld dword [ebx*4 + myfloatarr]
;st0 23.25 (raw 0x4003ba00000000000000)
;st1 0 (raw 0x00000000000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
; Allocate 8 bytes of stack space. Loading st0 and popping it
; converts the single precision number to double precision, which
; printf expects.
sub esp, byte 8
fstp qword [esp]
;st0 0 (raw 0x00000000000000000000)
;st1 0 (raw 0x00000000000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 23.25 (raw 0x4003ba00000000000000) ; the POP affected what st0 points to, but the value
; is still there in st7.
push dword myfloatstr
call printf
add esp, byte 12
; another example of the indexing for flt1[ 0 ]
mov ebx, 0
fld dword [ebx*4 + flt1]
;st0 12.340000152587890625 (raw 0x4002c570a40000000000)
;st1 0 (raw 0x00000000000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
inc ebx
fld dword [ebx*4 + flt1] for flt1[ 1 ]
;st0 23.450000762939453125 (raw 0x4003bb999a0000000000)
;st1 12.340000152587890625 (raw 0x4002c570a40000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
fadd st1
;st0 35.79000091552734375 (raw 0x40048f28f60000000000)
;st1 12.340000152587890625 (raw 0x4002c570a40000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
fstp dword [ flt2 ]
;st0 12.340000152587890625 (raw 0x4002c570a40000000000)
;st1 0 (raw 0x00000000000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 35.79000091552734375 (raw 0x40048f28f60000000000)
;(gdb) x/1wf &flt2
;0x8049482 : 35.7900009
fmul dword [ myfloatarr ]
;st0 286.90500354766845703125 (raw 0x40078f73d72800000000)
;st1 0 (raw 0x00000000000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 35.79000091552734375 (raw 0x40048f28f60000000000)
fstp dword [ flt2 + 4 ]
;st0 0 (raw 0x00000000000000000000)
;st1 0 (raw 0x00000000000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 35.79000091552734375 (raw 0x40048f28f60000000000)
;st7 286.90500354766845703125 (raw 0x40078f73d72800000000)
;(gdb) x/2wf &flt2
;0x8049486 : 35.7900009 286.904999
fild dword [ anInt ]
;st0 17 (raw 0x40038800000000000000)
;st1 0 (raw 0x00000000000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 35.79000091552734375 (raw 0x40048f28f60000000000)
; do the expression diameter = pi * r * r, where r = 20.3
;
; NOTE: Notice that 20.3 is not 20.3, but rather 20.299999237060546875
; This in an inherit error in the floating point conversions.
;
fld dword [ r ] ; get the value of r
;st0 20.299999237060546875 (raw 0x4003a266660000000000)
;st1 17 (raw 0x40038800000000000000)
;st2 0 (raw 0x00000000000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
fld st0 ; now have two copies of it on the stack
;st0 20.299999237060546875 (raw 0x4003a266660000000000)
;st1 20.299999237060546875 (raw 0x4003a266660000000000)
;st2 17 (raw 0x40038800000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
fmul st1 ; multiple st0 and st1
;st0 412.08996902465878520160913467407227 (raw 0x4007ce0b841ae1480000)
;st1 20.299999237060546875 (raw 0x4003a266660000000000)
;st2 17 (raw 0x40038800000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
fldpi ; load the value of pi into the FPU using built-in instruction
;st0 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)
;st1 412.08996902465878520160913467407227 (raw 0x4007ce0b841ae1480000)
;st2 20.299999237060546875 (raw 0x4003a266660000000000)
;st3 17 (raw 0x40038800000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
fmul st1 ; multiple st0 and st1
;st0 1294.6188193059134927676012694064411 (raw 0x4009a1d3cd5e25210516)
;st1 412.08996902465878520160913467407227 (raw 0x4007ce0b841ae1480000)
;st2 20.299999237060546875 (raw 0x4003a266660000000000)
;st3 17 (raw 0x40038800000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 0 (raw 0x00000000000000000000)
fstp dword [ diameter ] ; finish the expression.
;st0 412.08996902465878520160913467407227 (raw 0x4007ce0b841ae1480000)
;st1 20.299999237060546875 (raw 0x4003a266660000000000)
;st2 17 (raw 0x40038800000000000000)
;st3 0 (raw 0x00000000000000000000)
;st4 0 (raw 0x00000000000000000000)
;st5 0 (raw 0x00000000000000000000)
;st6 0 (raw 0x00000000000000000000)
;st7 1294.6188193059134927676012694064411 (raw 0x4009a1d3cd5e25210516)
;; terminate the program
mov ebx, 0
mov eax, 1
int 0x80