汇编语言浮点数指令集

合集下载

汇编浮点指令

汇编浮点指令

汇编浮点指令浮点数如何存储浮点数的运算完全不同于整数,从寄存器到指令,都有⼀套独特的处理流程,浮点单元也称作x87 FPU。

现在看浮点数的表⽰⽅式,我们所知道的,计算机使⽤⼆进制存储数据,所表⽰的数字都具有确定性,那是如何表⽰浮点这种具有近似效果的数据呢,答案是通过科学计数,科学计数由符号,尾数和指数表⽰,这三部分都是⼀个整数值,具体来看⼀下IEEE⼆进制浮点标准:格式说明单精度32位:符号占1位,指数占8位,尾数中的⼩数部分占23位双精度64位:符号占1位,指数占11位,尾数中的⼩数部分占52位扩展精度80位:符号占1位,指数占16位,尾数中的⼩数部分占63位以单精度为例,在内存中的储存格式如下(左边为⾼位):| 1位符号 | 8位指数 | 23位尾数 |其中符号位1表⽰负数,0表⽰正数,这与整数形式的符号位意义相同;科学计数法表⽰形式如 m * (b ^ e),m为尾数,b为基数,e是指数,再⼆进制中,基数毫⽆疑问是2,对单精度,指数为中间8位⼆进制表⽰的数字,其中的尾数是形如1.1101 ⼩数点后⾯的整数值。

关于指数,由于需要表⽰正负两种数据,IEEE标准规定单精度指数以127为分割线,实际存储的数据是指数加127所得结果,127为⾼位为零,后7位为1所得,其他双精度也以此⽅式计算。

为了解释内存中浮点数的存储⽅式,举⼀个浮点数的例⼦说明:float test = 123.456;int main(){return 0;}例⼦再简单不过了,仅仅定义了⼀个全局的float类型,我们通过gcc -S test.c来⽣成汇编,看看123.456是如何存储的,打开反汇编后的⽂件,看到符号_test后定义的数字是1123477881(这⾥gcc定义成了long类型,不过没有关系,因为都是四字节数字,具体的类型还得看如何使⽤)。

可以使⽤计算器把⼗进制数字转化为⼆进制:0 10000101 11101101110100101111001,这⾥根据单精度的划分⽅式把32位划分成三部分,符号位为0,为正数,指数为 133,减去127得6,尾数加上1.,形式为1.11101101110100101111001,扩⼤2 ^ 23次⽅为111101101110100101111001,⼗进制16181625,后除以2 ^ (23 – 6) = 131072,结果为123.45600128173828125,与我们所定义的浮点数正好相符。

浮点指令

浮点指令

浮点指令数据格式符号(Sign):表示数据正负,在最高数据位,正0负1指数(Exponent):也称阶码,以2为底的幂,采用偏移码表示,恒为整数有效数字(Significand):表示数据的有效位数,反应数据的精度单精度浮点数- 32位符号(1位)指数(8位)有效数字(23位)单精度格式8位指数的偏移基数为127阶码数值范围:-126 ~ 127双精度浮点数- 64位S - 1E - 11M - 52//===================================================== 浮点数据转实数表达式:(-1)^S × (1+M) ×2^E例:0x4996B438 - 1234567二进制数据:01001001100101101011010000111000符号- 0阶码- 147有效数字- 0.00101101011010000111000 b (0.177374839782715)浮点寄存器主要有通用数据寄存器、状态寄存器、控制寄存器、标记寄存器数据寄存器OD的浮点寄存器状态寄存器15 B 14C313-11TOP10C29C18C07ES6SF5PE4UE3OE2ZE1DEIEOD中的状态寄存器浮点指令取数指令取数值令从存储器或浮点数据寄存器中区的数据,压入寄存器栈顶st(0)。

FLD - 取存储器或st(i)中的浮点数,压入st(0)FILD - 取存储器的整数,压入st(0)存数指令存数,出栈FSTP - st(0)按浮点格式存入存储器或st(i),然后出栈FISTP - st(0)按整数格式存入存储器,然后出栈比较指令浮点比较指令比较栈顶数据与源操作数,结果通过状态寄存器反映。

状态寄存器中的C3 C2 C0用来反映比较结果,C1表示数据寄存器出现上溢或下溢。

比较指令的结果比较结果C3 C2 C0 st(0)>源操作数0 0 0st(0)<源操作数0 0 1st(0)=源操作数 1 0 0不可排序 1 1 1FCOM - 浮点数比较,st(0)和st(1)比较FCOMP - 浮点数比较,st(0)和st(1)比较并出栈运算指令FADD - st(0) += st(1)FSUB - st(0) -= st(1)FMUL - st(0) *= st(1)FDIV - st(0) /= st(1)FABS - st(0) = |st(0)|。

浮点数汇编指令集

浮点数汇编指令集

fsub st(num),st ;计算st(num)减st的值;用差值替换st(num)
fsub st,st(num) ;计算st减st(num)的值;用差值来替换st
fsub memory(real) ;计算st减存储器中的实型数的值;用差值来替换st
fidivr memory(integer);计算存储器中的整型数/st;用商来替换st
fdivrp st(num),st ;计算st/st(num)的值,用商来替换st(num);并将st出栈
;//////////////////////////////////////////////////////////////////////////////
fmul st(num),st ;将st(num)和st相乘;用乘积来替换st(num)
fmul st,st(num) ;将st和st(num)相乘;用乘积来替换st
fmul memory(real) ;将st和存储器中的实型数相乘;用乘积来替换st
fstp memory(real) ;复制st的值为实型数,存入存储器;st出栈
fist memory(integer) ;复制st的值,并转换为整型数存入存储器
fistp memory(integer) ;复制st的值,并转换为整型数存入存储器;st出栈
fbstp memory(BCD) ;复制st的值,并转换为BCD码存入存储器;st出栈
fimul memory(integer) ;将st和存储器中的整型数相乘,用乘积来替换st
fmulp st(num),st ;将st(num)和st相乘;乘积来替换st(num);并将st出栈
;助记符 操作数 功能

汇编语言只用ADD指令实现整数和浮点数的加减乘法

汇编语言只用ADD指令实现整数和浮点数的加减乘法
inputBAndSelect8 proc near
lea bx,user_string
mov ah,0ah
int 21h
mov ch,0
add bx,2;指向真正字符串开始的位置
mov ah,0
mov cl,8
add cl,255
beginin:
mov al,[bx]
add al,208;将字符串变为数值
rol bx,1;取第一个操作码到cf
jnc INTEGER;CF=0
jc others;CF=1
INTEGER:
rol bx,1;取第二个操作码到cf
jnc INTEGERadd;CF=0
jc INTEGERsub;CF=1
INTEGERadd:
call INTEGER_ADD
INTEGERsub:
mov bl,0
rol bx,cl;取第二个定点数放到bl
mov cl,bl;转存到cl
and cx,cx
jz FLOATadd
test cx,10h
jz FLOATsub
test cx,20h
jz FLOATmul
FLOATadd:
call FLOAT_ADD
FLOATsub:
call FLOAT_SUB
INTEGER_ADD proc near
mov bl,0
mov cl,3
rol bx,cl;取第一个操作数放到bl
mov ch,bl;转存到ch
mov bl,0
rol bx,cl;取第二个操作数放到bl
mov cl,bl;转存到ch
add ch,cl;第一个操作数和第二个操作数做加法
mov result,ch

ce 自动汇编 浮点

ce 自动汇编 浮点

ce 自动汇编浮点CE指的是8086微处理器的指令集架构中的Compare and Exchange指令,该指令用于实现多线程同步操作。

在汇编语言中,浮点数的处理涉及到浮点运算指令、浮点寄存器以及浮点数的格式。

我将按照以下几个方面详细介绍CE指令及相关内容。

一、浮点运算指令:在8086指令集中,浮点运算指令主要包括加法、减法、乘法和除法等。

这些指令利用浮点寄存器来进行计算。

具体的指令如下:1. FADD:浮点加法指令,用于对两个浮点数进行相加操作。

例如,FADD ST(0), ST(1)表示将ST(1)寄存器中的浮点数与ST(0)寄存器中的浮点数相加,并将结果存储在ST(0)寄存器中。

2. FSUB:浮点减法指令,用于对两个浮点数进行相减操作。

例如,FSUB ST(0), ST(1)表示将ST(1)寄存器中的浮点数减去ST(0)寄存器中的浮点数,并将结果存储在ST(0)寄存器中。

3. FMUL:浮点乘法指令,用于对两个浮点数进行相乘操作。

例如,FMUL ST(0), ST(1)表示将ST(1)寄存器中的浮点数与ST(0)寄存器中的浮点数相乘,并将结果存储在ST(0)寄存器中。

4. FDIV:浮点除法指令,用于对两个浮点数进行相除操作。

例如,FDIV ST(0), ST(1)表示将ST(1)寄存器中的浮点数除以ST(0)寄存器中的浮点数,并将结果存储在ST(0)寄存器中。

二、浮点寄存器:8086微处理器中的浮点数是通过浮点寄存器来进行存储和计算的。

浮点寄存器主要有FPU(浮点处理器单元)中的堆栈寄存器(ST)和数据寄存器(DR)。

1. 堆栈寄存器(ST):堆栈寄存器(ST)是存储浮点操作数的寄存器堆栈,它有8个寄存器(ST(0)-ST(7)),其中ST(0)是栈顶寄存器。

浮点运算指令通常通过操作堆栈中的寄存器来进行计算。

2. 数据寄存器(DR):数据寄存器(DR)用于存储浮点操作数的中间结果或者常数。

浮点运算指令309-319

浮点运算指令309-319

描述
当触发器变为ON时, 将由S1和S2指定浮点数(2字)相加. 结果存放到D+1和D. [S1+1, S1] + [S2+1, S2] → [D+1, D] 由[S1]和[S2]指定整型数据时, 在运算之前整型数将被转换为浮点数.
3-478
如果由[D]指定整型数, 则浮点数将被自动转换为整型数.
3-478
如果由[D]指定整型数, 则浮点数将被自动转换为整型数.
如果在S1或S2中指定了K常数, 则运算处理与指定整型数时的相同. 有关整型数处理的详细内容, 请参阅有关章节.
示例程序
当R0变为ON时, f5.432100被存放到DT30和DT31中.
编程时注意事项
本指令F313(F%)不能在中断程序中使用.
适用机型 FP-e/FP0/FP∑/FP2/FP2SH/FP10SH
概述 程序示例
将两个实数相乘, 结果存放到指定的32-bit存储区. FP0不支持P型的高级指令.
触发器
梯形图程序
S1 浮点数(32位)或32位数据的低16位的地址(被乘数).
S2 浮点数(32位)或32位数据的低16位的地址(乘数).
·错误标志(R9008) 当以下情况时瞬间变为ON - 使用索引寄存器指定数据区超出范围
3-483
F310(F+) P310(PF+)
浮点数加法
适用机型 FP-e/FP0/FP∑/FP2/FP2SH/FP10SH
概述 程序示例
将两个实数相加, 结果存放到指定的32-bit存储区. FP0不支持P型的高级指令.
继电器
WY WR AA AA AA
定时器计数器 数据寄存器 索引寄存器

汇编语言指令大全X86和X87汇编指令大全(带注释)

汇编语言指令大全X86和X87汇编指令大全(带注释)

汇编语⾔指令⼤全X86和X87汇编指令⼤全(带注释)⽬录⼀、数据传输指令1. 通⽤数据传送指令.2. 输⼊输出端⼝传送指令.3. ⽬的地址传送指令.4. 标志传送指令.⼆、算术运算指令三、逻辑运算指令四、串指令五、程序转移指令六、伪指令七、处理机控制指令&#xff1a;标志处理指令浮点运算指令集1、控制指令2、数据传送指令3、⽐较指令4、运算指令其它1.机械码,⼜称机器码.2.需要熟练掌握的全部汇编知识(只有这么多)3.常见修改(机器码)4.两种不同情况的不同修改⽅法⼀、数据传输指令它们在存贮器和寄存器、寄存器和输⼊输出端⼝之间传送数据.1. 通⽤数据传送指令.MOV 传送字或字节.MOVSX 先符号扩展,再传送.MOVZX 先零扩展,再传送.PUSH 把字压⼊堆栈.POP 把字弹出堆栈.PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压⼊堆栈.POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压⼊堆栈.POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.BSWAP 交换32位寄存器⾥字节的顺序XCHG 交换字或字节.(⾄少有⼀个操作数为寄存器,段寄存器不可作为操作数)CMPXCHG ⽐较并交换操作数.(第⼆个操作数必须为累加器AL/AX/EAX)XADD 先交换再累加.(结果在第⼀个操作数⾥)XLAT 字节查表转换.----BX指向⼀张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX&#43;AL]-&gt;AL)2. 输⼊输出端⼝传送指令.IN I/O端⼝输⼊. ( 语法: IN 累加器, {端⼝号│DX} )OUT I/O端⼝输出. ( 语法: OUT {端⼝号│DX},累加器 )输⼊输出端⼝由⽴即⽅式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535.3. ⽬的地址传送指令.LEA 装⼊有效地址.例: LEA DX,string ;把偏移地址存到DX.LDS 传送⽬标指针,把指针内容装⼊DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.LES 传送⽬标指针,把指针内容装⼊ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI.LFS 传送⽬标指针,把指针内容装⼊FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.LGS 传送⽬标指针,把指针内容装⼊GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.LSS 传送⽬标指针,把指针内容装⼊SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.4. 标志传送指令.LAHF 标志寄存器传送,把标志装⼊AH.SAHF 标志寄存器传送,把AH内容装⼊标志寄存器.PUSHF 标志⼊栈.POPF 标志出栈.PUSHD 32位标志⼊栈.POPD 32位标志出栈.⼆、算术运算指令ADD 加法.ADC 带进位加法.INC 加 1.AAA 加法的ASCII码调整.DAA 加法的⼗进制调整.SUB 减法.SBB 带借位减法.DEC 减 1.NEG 求反(以 0 减之).CMP ⽐较.(两操作数作减法,仅修改标志位,不回送结果).AAS 减法的ASCII码调整.DAS 减法的⼗进制调整.MUL ⽆符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),AAM 乘法的ASCII码调整.DIV ⽆符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或商回送AX,余数回送DX, (字运算).IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或商回送AX,余数回送DX, (字运算).AAD 除法的ASCII码调整.CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)三、逻辑运算指令AND 与运算.XOR 异或运算.NOT 取反.TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).SHL 逻辑左移.SAL 算术左移.(&#61;SHL)SHR 逻辑右移.SAR 算术右移.(&#61;SHR)ROL 循环左移.ROR 循环右移.RCL 通过进位的循环左移.RCR 通过进位的循环右移.以上⼋种移位指令,其移位次数可达255次.移位⼀次时, 可直接⽤操作码. 如 SHL AX,1.移位&gt;1次时, 则由寄存器CL给出移位次数.如 MOV CL,04 SHL AX,CL四、串指令DS:SI 源串段寄存器 :源串变址.ES:DI ⽬标串段寄存器:⽬标串变址.CX 重复次数计数器.AL/AX 扫描值.D标志 0表⽰重复操作中SI和DI应⾃动增量; 1表⽰应⾃动减量.Z标志⽤来控制扫描或⽐较操作的结束.MOVS 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )CMPS 串⽐较.( CMPSB ⽐较字符. CMPSW ⽐较字. )SCAS 串扫描.把AL或AX的内容与⽬标串作⽐较,⽐较结果反映在标志位.LODS 装⼊串.把源串中的元素(字或字节)逐⼀装⼊AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. ) STOS 保存串.是LODS的逆过程.REP 当CX/ECX&lt;&gt;0时重复.REPE/REPZ 当ZF&#61;1或⽐较结果相等,且CX/ECX&lt;&gt;0时重复.REPNE/REPNZ 当ZF&#61;0或⽐较结果不相等,且CX/ECX&lt;&gt;0时重复.REPC 当CF&#61;1且CX/ECX&lt;&gt;0时重复.REPNC 当CF&#61;0且CX/ECX&lt;&gt;0时重复.五、程序转移指令1. ⽆条件转移指令 (长转移)JMP ⽆条件转移指令CALL 过程调⽤RET/RETF 过程返回.2. 条件转移指令 (短转移,-128到&#43;127的距离内)( 当且仅当(SF XOR OF)&#61;1时,OP1&lt;OP2 )JA/JNBE 不⼩于或不等于时转移.JAE/JNB ⼤于或等于转移.JB/JNAE ⼩于转移.JBE/JNA ⼩于或等于转移.以上四条,测试⽆符号整数运算的结果(标志C和Z).JG/JNLE ⼤于转移.JGE/JNL ⼤于或等于转移.JL/JNGE ⼩于转移.JLE/JNG ⼩于或等于转移.以上四条,测试带符号整数运算的结果(标志S,O和Z).JE/JZ 等于转移.JNE/JNZ 不等于时转移.JC 有进位时转移.JNC ⽆进位时转移.JNO 不溢出时转移.JNP/JPO 奇偶性为奇数时转移.JNS 符号位为 &#34;0&#34; 时转移.JO 溢出转移.JP/JPE 奇偶性为偶数时转移.JS 符号位为 &#34;1&#34; 时转移.3. 循环控制指令(短转移)LOOP CX不为零时循环.LOOPE/LOOPZ CX不为零且标志Z&#61;1时循环.LOOPNE/LOOPNZ CX不为零且标志Z&#61;0时循环.JCXZ CX为零时转移.JECXZ ECX为零时转移.4. 中断指令INT 中断指令INTO 溢出中断IRET 中断返回5. 处理器控制指令HLT 处理器暂停, 直到出现中断或复位信号才继续.WAIT 当芯⽚引线TEST为⾼电平时使CPU进⼊等待状态.ESC 转换到外处理器.LOCK 封锁总线.NOP 空操作.STC 置进位标志位.CLC 清进位标志位.CMC 进位标志取反.STD 置⽅向标志位.CLD 清⽅向标志位.STI 置中断允许位.CLI 清中断允许位.六、伪指令DW 定义字(2字节).PROC 定义过程.ENDP 过程结束.SEGMENT 定义段.ASSUME 建⽴段寄存器寻址.ENDS 段结束.END 程序结束.七、处理机控制指令&#xff1a;标志处理指令CMC 进位位求反指令STC 进位位置为1指令CLD ⽅向标志置1指令STD ⽅向标志位置1指令CLI 中断标志置0指令STI 中断标志置1指令NOP ⽆操作HLT 停机WAIT 等待ESC 换码LOCK 封锁浮点运算指令集1、控制指令(带9B的控制指令前缀F变为FN时浮点不检查,机器码去掉9B)FINIT 初始化浮点部件机器码 9B DB E3FCLEX 清除异常机器码 9B DB E2FDISI 浮点检查禁⽌中断机器码 9B DB E1FENI 浮点检查禁⽌中断⼆机器码 9B DB E0WAIT 同步CPU和FPU 机器码 9BFWAIT 同步CPU和FPU 机器码 D9 D0FNOP ⽆操作机器码 DA E9FXCH 交换ST(0)和ST(1) 机器码 D9 C9FXCH ST(i) 交换ST(0)和ST(i) 机器码 D9 C1iiiFSTSW ax 状态字到ax 机器码 9B DF E0FSTSW word ptr mem 状态字到mem 机器码 9B DD mm111mmmFLDCW word ptr mem mem到状态字机器码 D9 mm101mmmFSTCW word ptr mem 控制字到mem 机器码 9B D9 mm111mmmFLDENV word ptr mem mem到全环境机器码 D9 mm100mmmFSTENV word ptr mem 全环境到mem 机器码 9B D9 mm110mmmFRSTOR word ptr mem mem到FPU状态机器码 DD mm100mmmFSAVE word ptr mem FPU状态到mem 机器码 9B DD mm110mmmFFREE ST(i) 标志ST(i)未使⽤机器码 DD C0iiiFDECSTP 减少栈指针1-&gt;0 2-&gt;1 机器码 D9 F6FINCSTP 增加栈指针0-&gt;1 1-&gt;2 机器码 D9 F7FSETPM 浮点设置保护机器码 DB E42、数据传送指令FLDZ 将0.0装⼊ST(0) 机器码 D9 EEFLD1 将1.0装⼊ST(0) 机器码 D9 E8FLDPI 将π装⼊ST(0) 机器码 D9 EBFLDL2T 将ln10/ln2装⼊ST(0) 机器码 D9 E9FLDL2E 将1/ln2装⼊ST(0) 机器码 D9 EAFLDLG2 将ln2/ln10装⼊ST(0) 机器码 D9 ECFLDLN2 将ln2装⼊ST(0) 机器码 D9 EDFLD real4 ptr mem 装⼊mem的单精度浮点数机器码 D9 mm000mmmFLD real8 ptr mem 装⼊mem的双精度浮点数机器码 DD mm000mmmFLD real10 ptr mem 装⼊mem的⼗字节浮点数机器码 DB mm101mmmFILD word ptr mem 装⼊mem的⼆字节整数机器码 DF mm000mmmFILD dword ptr mem 装⼊mem的四字节整数机器码 DB mm000mmmFILD qword ptr mem 装⼊mem的⼋字节整数机器码 DF mm101mmmFBLD tbyte ptr mem 装⼊mem的⼗字节BCD数机器码 DF mm100mmmFST real4 ptr mem 保存单精度浮点数到mem 机器码 D9 mm010mmmFST real8 ptr mem 保存双精度浮点数到mem 机器码 DD mm010mmmFIST word ptr mem 保存⼆字节整数到mem 机器码 DF mm010mmmFIST dword ptr mem 保存四字节整数到mem 机器码 DB mm010mmmFSTP real4 ptr mem 保存单精度浮点数到mem并出栈机器码 D9 mm011mmmFSTP real8 ptr mem 保存双精度浮点数到mem并出栈机器码 DD mm011mmmFSTP real10 ptr mem 保存⼗字节浮点数到mem并出栈机器码 DB mm111mmmFISTP word ptr mem 保存⼆字节整数到mem并出栈机器码 DF mm011mmmFISTP dword ptr mem 保存四字节整数到mem并出栈机器码 DB mm011mmmFISTP qword ptr mem 保存⼋字节整数到mem并出栈机器码 DF mm111mmmFBSTP tbyte ptr mem 保存⼗字节BCD数到mem并出栈机器码 DF mm110mmmFCMOVB ST(0),ST(i) &lt;时传送机器码 DA C0iiiFCMOVBE ST(0),ST(i) &lt;&#61;时传送机器码 DA D0iiiFCMOVE ST(0),ST(i) &#61;时传送机器码 DA C1iiiFCMOVNB ST(0),ST(i) &gt;&#61;时传送机器码 DB C0iiiFCMOVNBE ST(0),ST(i) &gt;时传送机器码 DB D0iiiFCMOVNE ST(0),ST(i) !&#61;时传送机器码 DB C1iiiFCMOVNU ST(0),ST(i) 有序时传送机器码 DB D1iiiFCMOVU ST(0),ST(i) ⽆序时传送机器码 DA D1iii3、⽐较指令FCOM ST(0)-ST(1) 机器码 D8 D1FCOMI ST(0),ST(i) ST(0)-ST(1) 机器码 DB F0iiiFCOMIP ST(0),ST(i) ST(0)-ST(1)并出栈机器码 DF F0iiiFCOM real4 ptr mem ST(0)-实数mem 机器码 D8 mm010mmmFCOM real8 ptr mem ST(0)-实数mem 机器码 DC mm010mmmFICOM word ptr mem ST(0)-整数mem 机器码 DE mm010mmmFICOM dword ptr mem ST(0)-整数mem 机器码 DA mm010mmmFICOMP word ptr mem ST(0)-整数mem并出栈机器码 DE mm011mmmFICOMP dword ptr mem ST(0)-整数mem并出栈机器码 DA mm011mmmFTST ST(0)-0 机器码 D9 E4FUCOM ST(i) ST(0)-ST(i) 机器码 DD E0iiiFUCOMP ST(i) ST(0)-ST(i)并出栈机器码 DD E1iiiFUCOMPP ST(0)-ST(1)并⼆次出栈机器码 DA E9FXAM ST(0)规格类型机器码 D9 E54、运算指令FADD 把⽬的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在⽬的操作数后的变量或堆栈缓存器) 相加&#xff0c;并将结果存⼊⽬的操作数FADDP ST(i),ST 这个指令是使⽬的操作数加上 ST 缓存器&#xff0c;并弹出 ST 缓存器&#xff0c;⽽⽬的操作数必须是堆栈缓存器的其中之⼀&#xff0c;最后不管⽬的操作数为何&#xff0c;经弹出⼀次后&#xff0c;⽬的操作数会变成上⼀个堆栈缓存器了FIADD FIADD 是把 ST 加上来源操作数&#xff0c;然后再存⼊ ST 缓存器&#xff0c;来源操作数必须是字组整数或短整数形态的变数FSUB 减FSUBPFSUBR 减数与被减数互换FSUBRPFISUBFISUBRFMUL 乘FMULPFIMULFDIV 除FDIVPFDIVRFDIVRPFIDIVFIDIVRFCHS 改变 ST 的正负值FABS 把 ST 之值取出&#xff0c;取其绝对值后再存回去。

浮点数运算指令整理

浮点数运算指令整理

st(0) st(0) st(0) st(0) st(0) st(0) st(0)
<- 0.0 <- 1.0 <- ?(ie, pi) <- log2(10) <- log2(e) <- log10(2) <- loge(2)
FST dest FSTP dest FIST dest FISTP dest FBST dest FBSTP dest 2.比较指令
<-st(0) + src (mem16/mem32)
st(0) <- st(0) - st(1) st(0) <-st(0) - src (reg/mem) st(i) <-st(i) - st(0) st(i) <-st(i) - st(0),然后执行一次出栈操

st(0) <- st(i) - st(0) st(0) <- st(i) - st(0),然后执行一次出
FSUBRP st(i),st
FISUB src FISUBR src 乘法 FMUL FMUL st(i) FMUL st(i),st
FMULP st(i),st
FIMUL src 除法 FDIV FDIV st(i) FDIV st(i),st
FDIVP st(i),st
FIDIV src FDIVR st(i),st
指令含义
FUCOMP st(i) FUCOMPP st(i) FXAM 3.运算指令
指令格式 加法 FADD FADD src FADD st(i),st
FADDP st(i),st
FIADD src 减法 FSUB FSUB src FSUB st(i),st
FSUBP st(i),st

汇编addss指令

汇编addss指令

汇编addss指令
ADDSS 是x86 架构下的SIMD (单指令多数据) 指令,属于SSE (Streaming SIMD Extensions) 指令集的一部分。

它主要用于浮点数计算。

ADDSS 指令执行单精度浮点数(32位)的加法操作。

它操作两个源操作数,并将结果存储在目标操作数中。

指令格式如下:
css
ADDSS xmm1, xmm2/m32
xmm1:目标操作数,一个128 位的XMM 寄存器,用于存储加法结果。

xmm2:第一个源操作数,也是一个128 位的XMM 寄存器。

m32:第二个源操作数,一个32 位的内存地址。

操作:
xmm2 的低32 位与m32 的内容进行加法操作。

结果存储在xmm1 的低32 位中,而xmm1 的高96 位保持不变。

注意:ADDSS 只操作低32 位的单精度浮点数,而忽略其他位。

在实际应用中,这种指令通常用于图形处理、物理模拟、科学计算等需要高速浮点运算的场景。

例如,下面的汇编代码展示了如何使用ADDSS 指令:
assembly
; 假设xmm0 中存储了一个单精度浮点数a
; 假设内存地址[address] 中也存储了一个单精度浮点数b
addss xmm0, [address] ; 将a 和b 相加,结果存储在xmm0 中
需要注意的是,为了充分发挥SSE 指令集的性能,通常需要结合其他指令和数据对齐技术来使用。

同时,现代的处理器和编译器也提供了更高级别的SIMD 指令集,如AVX、AVX2、AVX-512 等,这些指令集提供了更宽的数据路径和更多的操作功能。

汇编浮点运算指令集(转载)

汇编浮点运算指令集(转载)

汇编浮点运算指令集(转载)浮点执⾏环境的寄存器主要是8个通⽤数据寄存器和⼏个专⽤寄存器,它们是状态寄存器、控制寄存器、标记寄存器等8个浮点数据寄存器(FPU Data Register),编号FPR0 ~ FPR7。

每个浮点寄存器都是80位的,以扩展精度格式存储数据。

当其他类型数据压⼊数据寄存器时,PFU⾃动转换成扩展精度;相反,数据寄存器的数据取出时,系统也会⾃动转换成要求的数据类型。

8个浮点数据寄存器组成⾸尾相接的堆栈,当前栈顶ST(0)指向的FPRx由状态寄存器中TOP字段指明。

数据寄存器不采⽤随机存取,⽽是按照“后进先出”的堆栈原则⼯作,并且⾸尾循环。

向数据寄存器传送(Load)数据时就是⼊栈,堆栈指针TOP先减1,再将数据压⼊栈顶寄存器;从数据寄存器取出(Store)数据时就是出栈,先将栈顶寄存器数据弹出,再修改堆栈指针使TOP加1。

浮点寄存器栈还有⾸尾循环相连的特点。

例如,若当前栈顶TOP=0(即ST(0) = PFR0),那么,⼊栈操作后就使TOP=7(即使ST(0) = PFR7),数据被压⼊PFR7。

所以,浮点数据寄存器常常被称为浮点数据栈。

为了表明浮点数据寄存器中数据的性质,对应每个FPR寄存器,都有⼀个2位的标记(Tag)位,这8个标记tag0 ~ tag7组成⼀个16位的标记寄存器。

在计算机中,实数的浮点格式(Floating-Point Format)所⽰,分成指数、有效数字和符号位三个部分。

· 符号(Sign)——表⽰数据的正负,在最⾼有效位(MSB)。

负数的符号位为1,正数的符号为0。

· 指数(Exponent)——也被称为阶码,表⽰数据以2为底的幂。

指数采⽤偏移码(Biased Exponent)表⽰,恒为整数。

· 有效数字(Significand)——表⽰数据的有效数字,反映数据的精度。

有效数字⼀般采⽤规格化(Normalized)形式,是⼀个纯⼩数,所以也被称为尾数(Mantissa)、⼩数或分数(Fraction)。

运用TMS320C54x汇编语言编写定点数运算、浮点数运算程.

运用TMS320C54x汇编语言编写定点数运算、浮点数运算程.

一、定点数的运算在定点 DSP 芯片中,采用定点数进行数值运算,其操作数一般采用整数来表示。

一个整数的最大表示范围取决于 DSP 芯片所给定的字长,一般为 16位或 24位。

显然,字长越长,所能表示的数的范围越大, 精度也越高。

在字长固定的前提下, 所需要达到的精度越高, 那么所能表示的浮点数的范围就会越小。

DSP 芯片的数以 2的补码形式表示。

每个 16位数用一个符号位来表示数的正负, 0表示数值为正, l 则表示数值为负。

其余 15位表示数值的大小。

如:二进制数 0010000000000011b=8195二进制数 1111111111111100b= -4为了使得无论是无符号数还是符号数, 都可以使用同样的加法减法规则, 符号数中的负数用正数的补码表示。

对 DSP 芯片而言,参与数值运算的数就是 16位的整数。

但在许多情况下,数学运算过程中的数不一定都是整数。

那么, DSP 芯片是如何处理小数的呢?这其中的关键就是数的定标, 由程序员来确定一个数的小数点处于 16位中的哪一位。

通过设定小数点在 16位数中的不同位置, 就可以表示不同大小和不同精度的小数了。

数的定标有 Q 表示法和 S 表示法两种。

定点数的加减法运算较为简单,只需遵循二进制数加减法运算规则相加减即可。

如:两个 8位数具有相同的 Qn 格式,保证隐含的小数点对齐。

下图中两个 8位数相加, 有溢出。

溢出是由于字长有限运算结果超出数值的表示范围引起的。

定点数的乘法运算DSP 处理器都有硬件乘法器和乘法指令,可实现单周期乘法运算,二进制乘法运算包含一系列的移位和加法运算。

定点数乘法运算不要求相乘数有相同的 Qn 格式。

两个相乘数分别为 Qn 和 Qm 格式,字长为 N ,结果为 Q(n+m格式,字长为2N 。

如:以下两个相乘数分别为 Q7和 Q6格式, 8位字长。

两个定点小数作乘法运算,结果左移一位,保存高位得到运算结果,结果为 Qm (m nm 格式。

汇编 浮点指令

汇编 浮点指令

汇编浮点指令浮点指令是计算机中用于处理浮点数的指令集。

浮点数是一种用科学计数法表示的实数,由尾数和指数两部分组成。

在计算机系统中,浮点指令可以进行浮点数的加减乘除、取模、开方等运算,以及比较大小、转换格式等操作。

浮点指令的执行需要借助浮点单元,浮点单元通常是由专门的硬件电路实现的,它包括浮点寄存器、浮点运算器和控制单元等组件。

浮点寄存器用于存储浮点数的尾数和指数,浮点运算器用于执行浮点运算,控制单元用于控制浮点指令的执行顺序和结果的存储。

浮点单元通过执行浮点指令,可以有效地进行浮点数的运算。

浮点指令的格式通常由操作码和操作数组成。

操作码用于指定具体的操作,如加、减、乘、除等,操作数用于指定参与操作的浮点数。

浮点指令可以分为单精度和双精度两种形式,单精度指令用于处理32位浮点数,而双精度指令用于处理64位浮点数。

浮点指令的执行过程中,需要将操作数从内存中加载到浮点寄存器中,执行完毕后再将结果存回内存。

浮点指令的执行速度通常比整数指令慢,这是因为浮点数的运算涉及到较复杂的操作,需要较多的时钟周期来完成。

为了提高浮点指令的执行效率,现代计算机系统通常采用了各种优化技术,如流水线、超标量、乱序执行等。

这些技术可以并行执行多条浮点指令,提高浮点运算的吞吐量,从而加快计算速度。

浮点数在科学计算、图形处理、物理模拟等领域有着广泛的应用。

在科学计算中,浮点数常用于表示实验数据、模拟物理过程、求解数学方程等;在图形处理中,浮点数则用于表示三维坐标、颜色信息等;在物理模拟中,浮点数则用于模拟天体运动、流体流动等。

浮点指令的高效执行对于这些应用来说至关重要,它直接影响到计算的精度和速度。

浮点指令是计算机中用于处理浮点数的重要指令集。

它可以进行浮点数的各种运算和操作,为科学计算、图形处理、物理模拟等应用提供了强大的支持。

浮点指令的执行速度对于计算机的性能有着重要的影响,因此在设计和优化计算机系统时,需要充分考虑浮点指令的效率和性能。

Win32汇编-字符串浮点数运算过程

Win32汇编-字符串浮点数运算过程

Win32汇编-字符串浮点数运算过程整理复习汇编语⾔的知识点,以前在学习《Intel汇编语⾔程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为⽬的没有整理的很详细,这次是我第三次阅读此书,每⼀次阅读都会有新的收获,这次复习,我想把书中的重点,再⼀次做⼀个归纳与总结(注:16位汇编部分跳过),并且继续尝试写⼀些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,⼀些不重要的我就直接省略了,⼀来提⾼⾃⼰,⼆来分享知识,转载请加出处,敲代码备注挺难受的。

该笔记重点复习字符串操作指令的⼀些使⽤技巧,以及浮点数运算相关内容,浮点数运算也是⾮常重要的知识点,在分析⼤型游戏时经常会碰到针对浮点数的运算指令,例如枪械换弹动作,⼈物跳跃时的状态,都属于浮点数运算范围,也就⼀定会⽤到浮点数寄存器栈,浮点指令集主要可分为,传送指令,算数指令,⽐较指令,超越指令,常量加载指令等。

再次强调:该笔记主要学习的是汇编语⾔,不是研究编译特性的,不会涉及到编译器的优化与代码还原。

字符串操作指令移动串指令: MOVSB、MOVSW、MOVSD ;从 ESI -> EDI; 执⾏后, ESI 与 EDI 的地址移动相应的单位⽐较串指令: CMPSB、CMPSW、CMPSD ;⽐较 ESI、EDI; 执⾏后, ESI 与 EDI 的地址移动相应的单位扫描串指令: SCASB、SCASW、SCASD ;依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执⾏后 EDI ⾃动变化储存串指令: STOSB、STOSW、STOSD ;将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执⾏后 EDI ⾃动变化载⼊串指令: LODSB、LODSW、LODSD ;将 ESI 指向的数据载⼊到 AL/AX/EAX, 执⾏后 ESI ⾃动变化移动串指令: 移动串指令包括MOVSB、MOVSW、MOVSD原理为从ESI到EDI中,执⾏后将ESI地址⾥⾯的内容移动到EDI指向的内存空间中,该指令常⽤于对特定字符串的复制操作..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.data; 逐字节拷贝SrcString BYTE "hello lyshark",0h ; 源字符串SrcStringLen EQU $ - SrcString - 1 ; 计算出原始字符串长度DstString BYTE SrcStringLen dup(?),0h ; ⽬标内存地址szFmt BYTE '字符串: %s 长度: %d ',0dh,0ah,0; 四字节拷贝ddSource DWORD 10h,20h,30h ; 定义三个四字节数据ddDest DWORD lengthof ddSource dup(?) ; 得到⽬标地址.codemain PROC; 第⼀种情况: 实现逐字节拷贝cld ; 清除⽅向标志mov esi,offset SrcString ; 取源字符串内存地址mov edi,offset DstString ; 取⽬标字符串内存地址mov ecx,SrcStringLen ; 指定循环次数,为原字符串长度rep movsb ; 逐字节复制,直到ecx=0为⽌lea eax,dword ptr ds:[DstString]mov ebx,sizeof DstStringinvoke crt_printf,addr szFmt,eax,ebx; 第⼆种情况: 实现4字节拷贝lea esi,dword ptr ds:[ddSource]lea edi,dword ptr ds:[ddDest]cldrep movsd; 使⽤loop循环逐字节复制lea esi,dword ptr ds:[SrcString]lea edi,dword ptr ds:[DstString]mov ecx,SrcStringLencld ; 设置⽅向为正向复制@@: movsb ; 每次复制⼀个字节dec ecx ; 循环递减jnz @B ; 如果ecx不为0则循环lea eax,dword ptr ds:[DstString]mov ebx,sizeof DstStringinvoke crt_printf,addr szFmt,eax,ebxinvoke ExitProcess,0main ENDPEND main⽐较串指令: ⽐较串指令包括CMPSB、CMPSW、CMPSD⽐较ESI、EDI执⾏后将ESI指向的内存操作数同EDI指向的内存操作数相⽐较,其主要从ESI 指向内容减去EDI的内容来影响标志位..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.data; 逐字节⽐较SrcString BYTE "hello lyshark",0hDstStringA BYTE "hello world",0h.constszFmt BYTE '字符串: %s',0dh,0ah,0YES BYTE "相等",0NO BYTE "不相等",0.codemain PROC; 实现字符串对⽐,相等/不相等输出lea esi,dword ptr ds:[SrcString]lea edi,dword ptr ds:[DstStringA]mov ecx,lengthof SrcStringcldrepe cmpsbje L1jmp L2L1: lea eax,YESinvoke crt_printf,addr szFmt,eaxjmp lop_endL2: lea eax,NOinvoke crt_printf,addr szFmt,eaxjmp lop_endlop_end:int 3invoke ExitProcess,0main ENDPEND mainCMPSW 是对⽐⼀个字类型的数组,只有当数组中的数据完全⼀致的情况下才会返回真,否则为假..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.dataArray1 WORD 1,2,3,4,5 ; 必须全部相等才会清空ebxArray2 WORD 1,3,5,7,9.constszFmt BYTE '数组: %s',0dh,0ah,0YES BYTE "相等",0NO BYTE "不相等",0.codemain PROClea esi,Array1lea edi,Array2mov ecx,lengthof Array1cldrepe cmpswje L1lea eax,NOinvoke crt_printf,addr szFmt,eaxjmp lop_endL1: lea eax,YESinvoke crt_printf,addr szFmt,eaxjmp lop_endlop_end:int 3invoke ExitProcess,0main ENDPEND mainCMPSD则是⽐较双字数据,同样可⽤于⽐较数组,这⾥就演⽰⼀下⽐较单数的情况..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.datavar1 DWORD 1234hvar2 DWORD 5678h.constszFmt BYTE '两者: %s',0dh,0ah,0YES BYTE "相等",0NO BYTE "不相等",0.codemain PROClea esi,dword ptr ds:[var1]lea edi,dword ptr ds:[var2]cmpsdje L1lea eax,dword ptr ds:[YES]invoke crt_printf,addr szFmt,eaxjmp lop_endL1: lea eax,dword ptr ds:[NO]invoke crt_printf,addr szFmt,eaxjmp lop_endlop_end:int 3invoke ExitProcess,0main ENDPEND main扫描串指令: 扫描串指令包括SCASB、SCASW、SCASD其作⽤是把AL/AX/EAX中的值同EDI寻址的⽬标内存中的数据相⽐较,这些指令在⼀个长字符串或者数组中查找⼀个值的时候特别有⽤..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.dataszText BYTE "ABCDEFGHIJK",0.constszFmt BYTE '字符F所在位置: %d',0dh,0ah,0.codemain PROC; 寻找单⼀字符找到会返回第⼏个字符lea edi,dword ptr ds:[szText]mov al,"F"mov ecx,lengthof szText -1cldrepne scasb ; 如果不相等则重复扫描je L1xor eax,eax ; 如果没找到F则清空eaxjmp lop_endL1: sub ecx,lengthof szText -1neg ecx ; 如果找到输出第⼏个字符invoke crt_printf,addr szFmt,ecxlop_end:int 3main ENDPEND main如果我们想要对数组中某个值是否存在做判断可以使⽤SCASD指令,对数组进⾏扫描..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.dataMyArray DWORD 65,88,93,45,67,89,34,67,89,22.constszFmt BYTE '数值: %d 存在',0dh,0ah,0.codemain PROClea edi,dword ptr ds:[MyArray]mov eax,34mov ecx,lengthof MyArray - 1cldrepne scasdje L1xor eax,eaxjmp lop_endL1: sub ecx,lengthof MyArray - 1neg ecxinvoke crt_printf,addr szFmt,ecx,eaxlop_end:int 3main ENDPEND main储存串指令: 存储指令主要包括STOSB、STOSW、STOSD起作⽤是把AL/AX/EAX中的数据储存到EDI给出的地址中,执⾏后EDI的值根据⽅向标志的增加或减少,该指令常⽤于初始化内存或堆栈..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.dataCount DWORD 100String BYTE 100 DUP(?),0.codemain PROC; 利⽤该指令初始化字符串mov al,0ffh ; 初始化填充数据lea di,byte ptr ds:[String] ; 待初始化地址mov ecx,Count ; 初始化字节数cld ; 初始化:⽅向=前⽅rep stosb ; 循环填充; 存储字符串: 使⽤A填充内存lea edi,dword ptr ds:[String]mov al,"A"mov ecx,Countcldrep stosbint 3main ENDPEND main载⼊串指令: 载⼊指令主要包括LODSB、LODSW、LODSD起作⽤是将ESI指向的内存位置向AL/AX/EAX中装载⼀个值,同时ESI的值根据⽅向标志值增加或减少,如下分别完成加法与乘法计算,并回写到内存中..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.dataArrayW WORD 1,2,3,4,5,6,7,8,9,10ArrayDW DWORD 1,2,3,4,5ArrayMulti DWORD 10szFmt BYTE '计算结果: %d ',0dh,0ah,0.codemain PROC; 利⽤载⼊命令计算数组加法lea esi,dword ptr ds:[ArrayW]mov ecx,lengthof ArrayWxor edx,edxxor eax,eax@@: lodsw ; 将输⼊加载到EAXadd edx,eaxloop @Bmov eax,edx ; 最后将相加结果放⼊eaxinvoke crt_printf,addr szFmt,eax; 利⽤载⼊命令(LODSD)与存储命令(STOSD)完成乘法运算mov esi,offset ArrayDW ; 源指针mov edi,esi ; ⽬的指针cld ; ⽅向=向前mov ecx,lengthof ArrayDW ; 循环计数器L1: lodsd ; 加载[esi]⾄EAXmul ArrayMulti ; 将EAX乘以10stosd ; 将结果从EAX存储⾄[EDI]loop L1; 循环读取数据(存在问题)mov esi,offset ArrayDW ; 获取基地址mov ecx,lengthof ArrayDW ; 获取长度xor eax,eax@@: lodsdinvoke crt_printf,addr szFmt,eaxdec ecxloop @Bint 3main ENDPEND main统计字符串: 过程StrLength()通过循环⽅式判断字符串结尾的0标志,来统计字符串的长度,最后将结果存储在EAX中..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.dataString BYTE "hello lyshark",0szFmt BYTE '计算结果: %d ',0dh,0ah,0.code; 计算字符串长度StrLength PROC USES edi,pString:PTR BYTEmov edi,offset String ; 取出字符串的基地址xor eax,eax ; 清空eax⽤作计数器L1: cmp byte ptr [edi],0 ; 分别那[edi]的值和0作⽐较je L2 ; 上⼀步为零则跳转得到retinc edi ; 否则继续执⾏inc eaxjmp L1L2: retStrLength endpmain PROCinvoke StrLength, addr Stringinvoke crt_printf,addr szFmt,eaxint 3main ENDPEND main字符串转换: 字符串转换是将⼩写转为⼤写,或者将⼤写转为⼩写,其原理是将⼆进制位第五位置1或0则可实现. .386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.dataMyString BYTE "hello lyshark",0szFmt BYTE '结果: %s ',0dh,0ah,0.codemain PROCmov esi,offset MyString ; 取出字符串的偏移地址L1: cmp byte ptr [esi],0 ; 分别拿出每⼀个字节,与0⽐较je L2 ; 如果相等则跳转到L2and byte ptr [esi],11011111b ; 执⾏按位与操作inc esi ; 每次esi指针递增1jmp L1 ; 重复循环L2: lea eax,dword ptr ds:[MyString]invoke crt_printf,addr szFmt,eaxretmain ENDPEND main字符串拷贝: 使⽤两个指针分别指向两处区域,然后通过变址寻址的⽅式实现对特定字符串的拷贝..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.datasource BYTE "hello lyshark welcome",0htarget BYTE SIZEOF source DUP(0),0h ; 取源地址数据⼤⼩szFmt BYTE '结果: %s ',0dh,0ah,0.codemain PROC; 实现正向拷贝字符串mov esi,0 ; 使⽤变址寄存器mov ecx,sizeof source ; 循环计数器L1:mov al,byte ptr ds:[source + esi] ; 从源地址中取⼀个字符mov byte ptr ds:[target + esi],al ; 将该字符存储在⽬标地址中inc esi ; 递增,将指针移动到下⼀个字符loop L1lea eax,dword ptr ds:[target]invoke crt_printf,addr szFmt,eax; 实现反向拷贝字符串mov esi,sizeof sourcemov ecx,sizeof sourcemov ebx,0L2:mov al,byte ptr ds:[source + esi]mov byte ptr ds:[target + esi],aldec esiinc ebxloop L2lea eax,dword ptr ds:[target]invoke crt_printf,addr szFmt,eaxpush 0call ExitProcessmain ENDPEND main浮点数操作指令集(重点)浮点数的计算是不依赖于CPU的,运算单元是从80486处理器开始才被集成到CPU中的,该运算单元被称为FPU浮点运算模块,FPU不使⽤CPU 中的通⽤寄存器,其有⾃⼰的⼀套寄存器,被称为浮点数寄存器栈,FPU将浮点数从内存中加载到寄存器栈中,完成计算后在回写到内存中.FPU有8个可独⽴寻址的80位寄存器,分别名为R0-R7他们以堆栈的形式组织在⼀起,栈顶由FPU状态字中的⼀个名为TOP的域组成,对寄存器的引⽤都是相对于栈顶⽽⾔的,栈顶通常也被叫做ST(0),最后⼀个栈底则被记作ST(7)其实⽤⽅式与堆栈完全⼀致.浮点数运算通常会使⽤⼀些更长的数据类型,如下就是MASM汇编器定义的常⽤数据类型..datavar1 QWORD 10.1 ; 64位整数var2 TBYTE 10.1 ; 80位(10字节)整数var3 REAL4 10.2 ; 32位(4字节)短实数var4 REAL8 10.8 ; 64位(8字节)长实数var5 REAL10 10.10 ; 80位(10字节)扩展实数此外浮点数对于指令的命名规范也遵循⼀定的格式,浮点数指令总是以F开头,⽽指令的第⼆个字母则表⽰操作位数,例如:B表⽰⼆⼗进制操作数,I 表⽰⼆进制整数操作,如果没有指定则默认则是针对实数的操作fld等.FLD/FSTP 操作指令: 这两个指令是最基本的浮点操作指令,其中的FLD⼊栈指令,后⾯的FSTP则是将浮点数弹出堆栈..386p.model flat,stdcalloption casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libinclude msvcrt.incincludelib msvcrt.lib.datavar1 QWORD 10.0var2 QWORD 20.0var3 QWORD 30.0var4 QWORD 40.0result QWORD ?.codemain PROC; 初始化浮点单元finit; 依次将数据⼊栈fld qword ptr ds:[var1]fld qword ptr ds:[var2]fld qword ptr ds:[var3]fld qword ptr ds:[var4]; 获取当前ST(0)栈帧元素fst qword ptr ds:[result]; 从栈中弹出元素fstp qword ptr ds:[result]fstp qword ptr ds:[result]fstp qword ptr ds:[result]fstp qword ptr ds:[result]int 3main ENDPEND main压栈时会⾃动向下填充,⽽出栈时则相反,不但要出栈,还会将地址回绕到底部,覆盖掉底部的数据。

cpu浮点运算指令集

cpu浮点运算指令集

cpu浮点运算指令集
CPU的浮点运算指令集主要分为以下几种:
SSE指令集:SSE是Streaming SIMD Extensions的缩写,由于MMX指令并没有带来3D游戏性能的显著提升,所以,1999年Inter 公司在Pentium III CPU产品中推出了数据流单指令序列扩展指令(SSE)。

SSE兼容MMX指令,它可以通过SIMD(单指令多数据技术)和单时钟周期并行处理多个浮点来有效地提高浮点运算速度。

SSE2指令集:在Pentium 4 CPU中,Inter公司开发了新指令集SSE2。

这一次新开发的SSE2指令一共144条,包括浮点SIMD指令、整形SIMD指令、SIMD浮点和整形数据之间转换、数据在MMX寄存器中转换等几大部分。

其中重要的改进包括引入新的数据格式,如:128位SIMD整数运算和64位双精度浮点运算等。

SSE3指令集:相对于SSE2,SSE3又新增加了13条新指令,此前它们被统称为pni(prescott new instructions)。

13条指令中,一条用于视频解码,两条用于线程同步,其余用于复杂的数学运算、浮点到整数转换和SIMD浮点运算。

ce浮点数指令 -回复

ce浮点数指令 -回复

ce浮点数指令-回复浮点数指令(FPU)是计算机体系结构中的一种指令集,用于处理浮点数运算。

浮点数是一种用科学记数法表示的实数,由一个有效数字和一个指数组成。

浮点数指令允许计算机进行精确的浮点数运算,这在许多科学和技术领域中非常重要。

本文将逐步介绍浮点数指令的工作原理、使用方法和一些应用场景。

第一部分:浮点数的表示和存储(500字)在计算机中,浮点数通常以二进制形式进行存储和表示。

IEEE 754标准是现代计算机中最常用的浮点数表示方法。

根据这个标准,一个浮点数由三个部分组成:符号位、尾数和指数位。

符号位表示浮点数是正数还是负数,尾数表示浮点数的有效位数,指数位表示浮点数的放大因子。

浮点数的存储由两部分组成:浮点数的符号和尾数位存储在一个固定长度的位模式中,指数位则单独存储。

这种存储方式使得浮点数可以表示非常大或非常小的数字,而且具有可扩展性。

第二部分:浮点数指令的工作原理(500字)浮点数指令用于执行浮点数运算,如加法、减法、乘法和除法。

这些指令通常由专门的浮点单元执行,称为浮点处理器(FPU)。

浮点处理器是计算机中的一个独立芯片,其主要功能是执行浮点数运算。

浮点数指令的工作原理由几个步骤组成:首先,从内存或寄存器中加载要操作的浮点数。

然后,进行浮点数的运算,如加法或乘法。

运算结果存储在寄存器中,并根据需要进行舍入或截断。

最后,将结果存储回内存或寄存器中。

浮点数指令的工作原理还包括处理特殊情况,如零除错误或溢出错误。

当进行浮点数运算时,浮点处理器会检查这些特殊情况,并按照定义的规则进行处理。

第三部分:浮点数指令的使用方法(500字)浮点数指令可以通过汇编语言或高级编程语言使用。

在汇编语言中,程序员可以直接使用浮点寄存器和浮点指令。

在高级编程语言中,程序员可以使用浮点数数据类型和浮点数运算符,编译器会将这些操作转换为相应的浮点数指令。

使用浮点数指令时,需要注意浮点数的精度和舍入误差。

由于浮点数使用有限的位数来表示无限的实数,因此在进行浮点数运算时会存在一定的舍入误差。

ce 自动汇编 浮点 -回复

ce 自动汇编 浮点 -回复

ce 自动汇编浮点-回复自动汇编与浮点数运算:了解并提高性能引言:汇编语言是一种底层编程语言,直接操作计算机硬件,因此在对性能要求极高的场景下,使用汇编语言可以大大提高程序的运行效率。

而浮点数是一种用于表示实数的数值表示方法,广泛应用于科学计算、图形处理等领域。

本文将讨论如何使用自动汇编语言进行浮点数运算,在性能和精度之间找到平衡,并介绍如何利用现代计算机的特殊指令集提高浮点数计算的效率。

第一步:了解浮点数表示方式浮点数采用一种二进制科学记数法表示,通常由符号位、尾数位和指数位组成。

浮点数的精度取决于尾数位的位数,尾数位越多,精度就越高。

在自动汇编中,我们需要了解浮点数的内部表示方式,以便正确地进行运算。

第二步:选择合适的浮点数指令集现代计算机通常内置有专门的浮点数指令集,可以高效地执行浮点数运算。

在选择指令集时,需要考虑计算机硬件和软件之间的兼容性,以及指令集所支持的浮点数格式和精度。

例如,Intel的x87指令集支持80位的扩展浮点数运算,而SSE指令集则支持32位和64位的浮点数运算。

第三步:学习浮点数指令集和指令格式浮点数指令集通常包含一系列特定的指令,用于实现加、减、乘、除等浮点数运算。

通过学习浮点数指令集的指令格式和功能,我们可以了解如何正确地使用这些指令进行浮点数运算。

第四步:编写浮点数运算的自动汇编程序在自动汇编程序中,我们需要根据浮点数的内部表示和指令集的要求,将浮点数数据加载到寄存器中,并使用浮点数指令进行运算。

在编写程序时,需要特别注意运算过程中的溢出、舍入误差等问题,以确保计算结果的正确性和精度。

第五步:优化浮点数运算的性能除了正确地实现浮点数运算之外,我们还可以通过一些技巧来进一步提高运算性能。

例如,可以使用寄存器重命名技术来减少数据依赖性,采用循环展开技术来增加指令级并行性,利用SIMD指令集来进行多数据并行计算等。

第六步:验证浮点数运算的正确性和精度在编写完自动汇编程序后,我们需要对程序进行验证,以确保计算结果的正确性和精度。

汇编addss指令

汇编addss指令

汇编addss指令全文共四篇示例,供读者参考第一篇示例:汇编语言是一种底层的程序设计语言,与机器语言的指令一一对应。

在汇编语言中,有许多指令可以用来完成不同的操作,其中addss指令是用来实现浮点数相加的指令之一。

addss指令用于将两个单精度浮点数相加,并将结果存储到目标操作数中。

这个指令的具体操作过程是将源操作数的值加到目标操作数的值上,并将结果存储到目标操作数中。

addss指令的语法格式通常如下:addss 目标操作数,源操作数在汇编语言中使用addss指令进行浮点数相加的操作通常需要以下几个步骤:1. 将要相加的单精度浮点数加载到寄存器中。

2. 使用addss指令将两个单精度浮点数相加,并将结果存储到目标操作数中。

3. 可以选择将结果存储到寄存器中或者内存地址中,根据需要进行操作。

下面通过一个简单的汇编语言示例来演示addss指令的使用过程:```assemblysection .datafloat1 dd 3.14 ; 定义一个单精度浮点数变量float1,初始化值为3.14float2 dd 2.72 ; 定义一个单精度浮点数变量float2,初始化值为2.72result dd 0 ; 定义一个单精度浮点数变量result,用于保存计算结果; 退出程序mov eax, 1 ; 调用exit系统调用xor ebx, ebxint 0x80```在这个示例中,我们定义了两个单精度浮点数变量float1和float2,然后使用addss指令将它们相加,并将结果保存在result变量中。

最后通过exit系统调用退出程序。

addss指令是汇编语言中用于单精度浮点数相加的指令,通过这个指令可以实现对浮点数的加法运算。

在实际开发中,我们可以根据需要使用addss指令来完成浮点数相加的操作,从而实现更加复杂的计算和处理。

【以上内容仅供参考,实际操作中需要根据具体情况进行调整】。

第二篇示例:汇编语言是一种底层的计算机语言,它直接操作计算机的硬件资源,包括寄存器、内存和输入输出设备。

汇编fld指令

汇编fld指令

汇编语言中的fld指令用于加载浮点数到寄存器。

下面是对fld指令的800字描述:
fld指令是x86汇编语言中的一条指令,用于将内存中的浮点数加载到指定的寄存器中。

fld 指令通常用于处理浮点数运算,例如浮点数的加法、减法、乘法、除法等操作。

fld指令有多个不同的变种,例如fld st(n),其中st(n)是一个寄存器堆栈指针,用于加载存储在内存中的浮点数到指定的寄存器中。

此外,fld指令还可以用于加载内存中的单精度浮点数或双精度浮点数。

在执行fld指令时,首先会将内存中的浮点数加载到相应的寄存器中,这通常涉及到将浮点数从IEEE 754标准中的浮点格式转换为x86架构中的浮点格式。

转换过程中需要考虑浮点数的符号位、指数位和尾数位,以确保正确的加载和存储。

fld指令在计算机科学和工程中具有广泛的应用,尤其是在科学计算、数值分析、金融和工程领域中。

通过使用fld指令,开发人员可以更轻松地处理浮点数运算,提高程序的性能和准确性。

除了fld指令本身,还需要考虑其他因素,例如内存布局、寄存器选择和指令顺序等,以实现最佳的浮点数处理效果。

fld指令通常与其他指令一起使用,例如fadd、fmul、fsub等,以完成更复杂的浮点数运算任务。

总之,fld指令在x86汇编语言中具有重要作用,用于加载浮点数到寄存器,并在各种计算任务中发挥关键作用。

了解fld指令的工作原理和最佳实践对于编写高效、准确的浮点数处理程序至关重要。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

fsubr st(num),st ;计算 st 减 st(num)的值,用差值替换 st(num)
fsubr st,st(num) ;计算 st(num)减 st 的值,用差值来替换 st
fsubr memory(real) ;计算存储器中的实型数值减 st 的值,用差值替换 st
fisubr memory(integer) ;计算存储器中的整型数值减 st 的值;用差值替换 st
;///
;////////////////////////////////////////////////////////////////////////////
;助记符 操作数
功能
fcom (none)
;比较 st 和 st(1)
fcom st(num)
;比较 st 和 st(num)
fcom memory(real) ;比较 st 和存储器中的实型数
fmul st,st(num) ;将 st 和 st(num)相乘;用乘积来替换 st
fmul memory(real) ;将 st 和存储器中的实型数相乘;用乘积来替换 st
fimul memory(integer) ;将 st 和存储器中的整型数相乘,用乘积来替换 st
fmulp st(num),st ;将 st(num)和 st 相乘;乘积来替换 st(num);并将 st 出栈
汇编语言浮点数指令集
;****************************************************************
****************
;*
浮点数指令集
;****************************************************************
ficom memory(integer) ;比较 st 和存储器中的整型数
ftst (none)
;比较 st 和 0.0
fcomp (none)
;比较 st 和 st(1);然后出栈
fcomp st(num)
;比较 st 和 st(num);然后出栈
fcomp memory(real) ;比较 st 和存储器中的实型数;然后出栈
;1.0 压人堆栈
fldz (none)
;0.0 压人堆栈
fldpi (none)
;Π(pi)压人堆栈
fldl2e (none)
;log2(e)压人堆栈
fldl2t (none)
;log2(10)压人堆栈
fldlg2 (none)
;log10(2)压人堆栈
fldln2 (none)
;loge(2)压人堆栈
fsubrp st(num),st ;计算 st 减 st(num)的值,用差值替换 st(num);将 st 出栈
;//////////////////////////////////////////////////////////////////////////////
;///
;///
浮点型除法指令
finit (none)
;初始化浮点型单元,并清空 8 个寄存器的内容
;////////////////////////////////////////////////////////////////////////////////
;/////
;////
浮点数数据存储指令
;////
;///////////////////////////////////////////////////////////////////////////////
;////
;///
浮点型乘法指令
;///
;//////////////////////////////////////////////////////////////////作数
功能
fmul (none)
;将 st 和 st(1)出栈;并将它们的值相乘;乘积人栈
fmul st(num),st ;将 st(num)和 st 相乘;用乘积来替换 st(num)
fiadd memory(integer) ;将 st 和存储器中的整型数相加,用和替换 st
faddp st(num),st ;将 st(num)和 st 相加,用和来替换 st(num),将 st 出栈
;//////////////////////////////////////////////////////////////////////////////
fcomp memory(integer) ;比较 st 和存储器中的整型数;然后出栈
fcompp (none)
;比较 st 和 st(1);然后两次出栈
;////////////////////////////////////////////////////////////////////////////
;助记符 操作数
功能
fst st(num)
;复制 st 的值来替换 st(num)的内容;只有 st(num)是受到影响
fstp st(num)
;复制 st 的值来替换 st(num)的内容;st 出栈
fst memory(real) ;复制 st 的值为实型数,存入存储器;堆栈不受影响
fstp memory(real) ;复制 st 的值为实型数,存入存储器;st 出栈
;互换 st 和 st(1)
fxch st(num)
;互换 st 和 st(num)
;///////////////////////////////////////////////////////////////////////////////
;////
;///
浮点型加法指令
;///
;//////////////////////////////////////////////////////////////////////////////
;助记符 操作数
功能
fsub (none)
;将 st 和 st(1)出栈,计算 st(1)减 st 的值;将差入栈
fsub st(num),st ;计算 st(num)减 st 的值;用差值替换 st(num)
fsub st,st(num) ;计算 st 减 st(num)的值;用差值来替换 st
fsub memory(real) ;计算 st 减存储器中的实型数的值;用差值来替换 st
fstcw memory WORD ;复制控制字寄存器到存储器
fldcw memory WORD ;复制存储器字到控制字寄存器
****************
;////////////////////////////////////////////////////////////////////////////////
;////
;////
浮点数载入指令
;////
;///////////////////////////////////////////////////////////////////////////////
fisub memory(integer) ;计算 st 减存储器中的整型数的值;用差值替换 st
fsubp st(num),st ;计算 st(num)减 st 的值;用差值替换 st(num);将 st 出栈
fsubr (none)
;将 st 和 st(1)出栈;计算 st 减 st(1)的值;将差值入栈
功能 ;st := |st|(绝对值) ;st := -st(相反数) ;对 st 取整 ;用 st 的平方根来替换 st
;/////////////////////////////////////////////////////////////////////////////
;///
;///
浮点型比较指令
;///
;///
附加的浮点型指令
;///
;/////////////////////////////////////////////////////////////////////////////
;助记符 操作数 fabs (none) fchs (none) frndint (none) fsqrt (none)
;助记符 操作数
功能
fld memory(real) ;将存储器中的实型压人堆栈
fild memory(integer) ;将存储器的整型数值转化为浮点数并压人堆栈
fbld memory(BCD) ;将存储器的 BCD 码转化为浮点数并压人堆栈
fld st(num)
;将浮点型寄存器中的数值压入堆栈
fld1 (none)
;助记符 操作数
功能
fadd (none)
;将 st 和 st(1)出栈;将两个值相加;并将它们的和入栈
fadd st(num),st ;将 st(num)和 st 相加;用和替换 st(num)
fadd st,st(num) ;将 st 和 st(num)相加;用和替换 st
fadd memory(real) ;将 st 和存储器中的实型数相加;用和替换 st
fist memory(integer) ;复制 st 的值,并转换为整型数存入存储器
fistp memory(integer) ;复制 st 的值,并转换为整型数存入存储器;st 出栈
fbstp memory(BCD) ;复制 st 的值,并转换为 BCD 码存入存储器;st 出栈
fxch (none)
;///
;///
混合浮点型指令
;///
;////////////////////////////////////////////////////////////////////////////
相关文档
最新文档