汇编学习笔记整理之算数指令
鉴于之前学习代码的时候总是因为没有在课后整理笔记并且重新复习而导致知识点掌握不熟练的后果,现在将每次学习的笔记整理至csdn博客中。以便更好的督促自己学习
一、前览
算数指令主要有求平方根FSQRT、求绝对值FABS、求负数FCHS、取实数阶码和尾数FXTRACT、取实数余数FPREM/FPREM1、就近舍入取整FRNDINT、求2的指数FSCALE/F2XM1、求以2为底的对数FYL2X[P1]和三角函数等。
二、指令
1.实数平方根:FSQRT
实例:
.386 ;选择的处理器
.model flat, stdcall
option casemap:none ;指明标识符大小写敏感
include kernel32.inc ;要引用的头文件
includelib kernel32.lib ;要引用的库文件
includelib msvcrt.lib ;引用C库文件
scanf PROTO C:DWORD,:vararg ;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data ;⑤数据段
x QWORD ?
a QWORD ?
b QWORD ?
d QWORD 2.0
f QWORD ?
m QWORD ?
n QWORD ?
z QWORD ?
p QWORD ?
fmt db '%lf',0
fmt1 db '%.2lf',0
.code
start:
invoke scanf,addr fmt,addr x
FLD x
FSIN ;求sin函数
FSTP a
FLD x
FCOS ;求cos函数
FSTP b
FLD b
FADD d
FSTP f
FLD a
CDQ
FDIV f
FSTP m
FLD x
FMUL x
FSTP n
FLD n
FADD m
FSTP z
FLD z
FSQRT ;求算数平方根
FSTP p
invoke printf,addr fmt1,p
ret
end start
2.求绝对值:FABS
实例:
FLD y
FABS
FSTP x
3.求负数:FCHS
实例:
FLD x
FCHS
FSTP y
4.取余数:FPREM/FPREM1
FPREM指令的功能是求st(0)除以st(1)的余数,即st(0)-Qst(1),执行FPREM时Q为st(0)/st(1)取整的结果,执行FPREM1时Q为st(0)/st(1)就近舍入*
实例:
.386 ;选择的处理器
.model flat, stdcall
option casemap:none ;指明标识符大小写敏感
include kernel32.inc ;要引用的头文件
includelib kernel32.lib ;要引用的库文件
includelib msvcrt.lib ;引用C库文件
scanf PROTO C:DWORD,:vararg ;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data ;⑤数据段
x QWORD ?
y QWORD 1.0
a QWORD ?
b QWORD ?
fmt db '%lf',0
fmt1 db '%g %g',0
.code
start:
invoke scanf,addr fmt,addr x
FLD y ;y作为st(1)先加载
FLD x ;x作为st(0)后加载
FPREM ;st(0)=x-x/y*y,此处的x/y取整
FSTP a
FLD x
FSUB a
FSTP b
invoke printf,addr fmt1,b,a
ret
end start
5.求2的指数:FSCALE/F2XM1
FSCALE求当n为整数时的情况,F2XM1求当n为小数时的情况
Ⅰ:FSCALE
FSCALE指令的功能是st(0)*2^st(1),其中st(1)先向零取整后再计算
实例:
.386 ;选择的处理器
.model flat, stdcall
option casemap:none ;指明标识符大小写敏感
include kernel32.inc ;要引用的头文件
includelib kernel32.lib ;要引用的库文件
includelib msvcrt.lib ;引用C库文件
scanf PROTO C:DWORD,:vararg ;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data ;⑤数据段
x QWORD ?
y QWORD ?
a QWORD ?
b QWORD ?
fmt db '%lf%lf',0
fmt1 db '%g*2^%g=%g',0
.code
start:
invoke scanf,addr fmt,addr x,addr y
fld y ;y作为st(1)先加载
fld x ;x作为st(0)后加载
FSCALE ;st(0)=x*2^y,y在此处要取整
fstp a
fstp b
invoke printf,addr fmt1,x,b,a
ret
end start
Ⅱ:F2XM1
F2XM1指令的功能是求2^st(0)-1,st(0)介于-1~1之间
实例:
.386 ;选择的处理器
.model flat, stdcall
option casemap:none ;指明标识符大小写敏感
include kernel32.inc ;要引用的头文件
includelib kernel32.lib ;要引用的库文件
includelib msvcrt.lib ;引用C库文件
scanf PROTO C:DWORD,:vararg ;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data ;⑤数据段
x QWORD ?
a QWORD ?
b QWORD 1.0
d QWORD ?
fmt db '%lf',0
fmt1 db '%.3lf',0
.code
start:
invoke scanf,addr fmt,addr x
fld x
F2XM1 ;st(0)=2^x-1
fadd b ;现在此处加上1,避免x的符号改变
fstp a
invoke printf,addr fmt1,a
ret
end start
6.求以2为底的对数:FYL2X / FYL2XP1
Ⅰ:FYL2X
FYL2X指令的功能是求st(1)*log2st(0)结果存st(1),然后st(0)出栈
实例:
.386 ;选择的处理器
.model flat, stdcall
option casemap:none ;指明标识符大小写敏感
include kernel32.inc ;要引用的头文件
includelib kernel32.lib ;要引用的库文件
includelib msvcrt.lib ;引用C库文件
scanf PROTO C:DWORD,:vararg ;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data ;⑤数据段
x QWORD ?
y QWORD ?
b QWORD ?
fmt db '%lf %lf',0
fmt1 db '%g',0
.code
start:
invoke scanf,addr fmt,addr x,addr y
FLDLG2 ;将log~10~2加载到st(0),即st(0)=log~10~2
FMUL x
FLD y
FYL2X
fstp b
invoke printf,addr fmt1,b
ret
end start