Upload
akirank1
View
107
Download
0
Embed Size (px)
DESCRIPTION
Professional Assembly Language
Citation preview
CS220
April 18, 2007
Floating Point Instructions• filds/fildl Loads 32 bits integer into FPU• fists/fistl Stores top reg value to 32 bits memory• fbld Loads BCD• fbst Stores BCD• fadd Floating-point addition• fdiv Floating-point division• fdivr Reverse floating-point division• fmul Floating-point multiplication• fsub Floating-point subtraction• fsubr Reverse floating-point subtraction• frndint Rounds the value in st(0) to the nearest int• fsqrt Computes the square root of the value in st(0)• fxch Exchange registers
Note: FP instructions can’t use immediate number as operand, and can’t use one FP reg and one memory variable. You need to worry about s/l surffix only when dealing with memory. i.e. fadds -4(%ebp) but fadd %st(1), %st(2)
Examples• fadds data1
– add the 32-bit value at data1 to the st(0) register• fmull data1
– multiply the 64-bit value at data1 with the st0 register• fidiv data1
– divide st(0) by the 32-bit integer value at data1, and store in st(0)• fsub %st(0), %st(1)
– st(1)= st(0) - st(1)• fsubr %st(0), %st(1)
– st(1)= st(1) - st(0)• fdivs data1
– devide the value st(0) by data1, and store in st(0)• faddp
– Add st(0) to st(1), store the result in st(1), and pop st(0)• flds var1
flds var2fdivp
– var2 at st(0) is divided by var1 at st(1), store in st(1) then pop, result now in st(0)
No operand:st(0) and st(1)
One operand:st(0) omitted
Compare: subl %eax, %ebx%ebx=%ebx-%eax
pop after operations
• fstp• fistp• faddp• fsubp• fmulp• fdivp• …
After pop:
st(1) ->st(0)
st(2)->st(1)
…
st(0)->st(7) (invalid value, can’t be used)
fld1fldzflds var1fldpi
faddp
fadds var2
fadd %st(0), %st(2)
st0 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)st1 1.10000002384185791015625 (raw 0x3fff8ccccd0000000000)st2 0 (raw 0x00000000000000000000)st3 1 (raw 0x3fff8000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 0 (raw 0x00000000000000000000)
st0 4.2415926774316511484522185249090853 (raw 0x400187bb209110b4611a)st1 0 (raw 0x00000000000000000000)st2 1 (raw 0x3fff8000000000000000)st3 0 (raw 0x00000000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)
st0 6.4415927251153669687647185249090853 (raw 0x4001ce21871110b4611a)st1 0 (raw 0x00000000000000000000)st2 1 (raw 0x3fff8000000000000000)st3 0 (raw 0x00000000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)
st0 6.4415927251153669687647185249090853 (raw 0x4001ce21871110b4611a)st1 0 (raw 0x00000000000000000000)st2 7.4415927251153669687647185249090853 (raw 0x4001ee21871110b4611a)st3 0 (raw 0x00000000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)
(var1=1.1, var2=2.2)
invalid
float add(float a,float b){
return a+b;}
.text.globl add
.type add, @functionadd:
pushl %ebpmovl %esp, %ebpflds 8(%ebp)fadds 12(%ebp)leaveret.size add, .-add
void main(){
float f1=1.1f,f2=2.2f;printf("f1 + f2 = %f\n",add(f1,f2));
}
.section .rodata.LC3:
.string "f1 + f2 = %f\n"
.text.globl main
.type main, @functionmain:
pushl %ebpmovl %esp, %ebpsubl $8, %espmovl $0x3f8ccccd, %eaxmovl %eax, -4(%ebp)movl $0x400ccccd, %eaxmovl %eax, -8(%ebp)pushl -8(%ebp)pushl -4(%ebp)call addaddl $8, %espsubl $8, %esp # leal -8(%esp), %espfstpl (%esp)pushl $.LC3call printfaddl $12, %espleaveret.size main, .-main
double mul(double a,double b){
return a*b;}
.text.globl mul
.type mul, @functionmul:
pushl %ebpmovl %esp, %ebpfldl 8(%ebp) fmull 16(%ebp)leaveret.size mul, .-mul
void main(){
double d1=1.1, d2=2.2;printf("d1 + d2 = %f\n",mul(d1,d2));
}
.section .rodata.LC3:
.string "f1 + f2 = %f\n" .text.globl main
.type main, @functionmain:
pushl %ebpmovl %esp, %ebpsubl $16, %espmovl $1072798105, %edxmovl $-1717986918, %eaxmovl %edx, -4(%ebp)movl %eax, -8(%ebp)movl $1073846681, %edxmovl $-1717986918, %eaxmovl %edx, -12(%ebp)movl %eax, -16(%ebp)pushl -12(%ebp)pushl -16(%ebp)pushl -4(%ebp)pushl -8(%ebp)call muladdl $16, %espsubl $8, %esp # leal -8(%esp), %espfstpl (%esp)pushl $.LC3call printfaddl $12, %espleaveret
#a: 8(%ebp) and 12(%ebp)
#b: 16(%ebp) and 20(%ebp)
#d1’s low part#d1’s high part
#d1’s high part#d1’s low part
Little Endian:
Use lower 32-bit address to access a 64 bits number
Little Endian:
High part high address
Low part low address
Rounding Example• Control reg 10–11 Rounding control
00 - round to nearest (default)01 - round down (toward negative
infinity)10 - round up (toward positive infinity)11 - round toward zero
pushfpush %eax
finitflds value1frndintfists resultnearest
fstcw tmpmovw tmp, %axandw $0b1111001111111111, %axorw $0b0000010000000000, %axmovw %ax, tmpfldcw tmpflds value1frndintfists resultdown
popl %eaxpopfleaveret.size main, .-main
.section .datavalue1:
.float 3.65.section .bss
.lcomm resultnearest, 4
.lcomm resultdown, 4
.lcomm tmp, 2.text.globl main
.type main, @functionmain:
pushl %ebpmovl %esp, %ebp
4
3
Reverse Polish Notation (RPN)• Infix notation: x * y• RPN: x y *
• Example:x = ((y-z)*a) - ( a + b * c )/3.14159
x = ([y z -] * a) - ( a + b * c )/3.14159x = [y z - a *] - ( a + b * c )/3.14159x = [y z - a *] - ( a + [b c *])/3.14159x = [y z - a *] - [a b c * +]/3.14159x = [y z - a *] - [a b c * + 3.14159 /]x = [y z - a *] [a b c * + 3.14159 /] -x = y z - a * a b c * + 3.14159 / -
((43.65 / 22) + (76.34 * 3.1)) / ((12.43 * 6) – (140.2 / 94.21))
1. Load 43.65 into st(0).2. Divide st(0) by 22, saving the results in st(0).3. Load 76.34 in st(0) (the answer from step 2 moves to st(1)).4. Load 3.1 in st(0) (the value in step 3 moves to st(1), and the answer from Step 2 moves
to st(2)).5. Multiply st(0) and st(1), leaving the answer in st(0).6. Add st(0) and st(2), leaving the answer in st(0) (this is the left side of the equation).7. Load 12.43 into st(0) (the answer from Step 6 moves to st(1)).8. Multiply st(0) by 6, leaving the answer in st(0).9. Load 140.2 into st(0) (the answer from Step 8 moves to st(1), and from Step 6 to st(2)).10. Load 94.21 into st(0) (the answer from Step 8 moves to st(2), and from Step 6 to ST3).11. Divide st(1) by st(0), popping the stack and saving the results in st(0) (the answer from
Step 812. moves to st(1), and from Step 6 to st(2)).13. Subtract st(0) from st(1), storing the result in st(0) (this is the right side of the equation).14. Divide st(2) by st(0), storing the result in st(0) (this is the final answer).
This example comes from recommended textbook; it doesn’t really follow RPN notation
((43.65 / 22) + (76.34 * 3.1)) / ((12.43 * 6) – (140.2 / 94.21))
.section .datavalue1:
.float 43.65value2:
.int 22value3:
.float 76.34value4:
.float 3.1value5:
.float 12.43value6:
.int 6value7:
.float 140.2value8:
.float 94.21output:
.string "The result is %f\n"
.text.globl main
.type main, @functionmain:
pushl %ebpmovl %esp, %ebp
finitflds value1fidiv value2flds value3flds value4fmul %st(1), %st(0)fadd %st(2), %st(0)flds value5fimul value6flds value7flds value8fdivrpfsubr %st(1), %st(0)fdivr %st(2), %st(0)subl $8, %espfstpl (%esp)pushl $outputcall printfadd $12, %esp
leaveret.size main, .-main
((43.65 / 22) + (76.34 * 3.1)) /
((12.43 * 6) – (140.2 / 94.21))