一个测试mxcsr 指令的汇编源码。

Peirre11个月前我的程序176

mxcsr 是多媒体指令集的一个。这个指令可以读一般指令读取不到的空间。

主程序 mxcsr.asm

; mxcsr.asm

; 浮点操作的SSE控制和状态寄存器----mxcsr,它是一个32位寄存器,只使用较低的16位。
; 
; mxcsr 指令的异常位
; 
; 0 IE 无效的操作错误
; 1 DE 非规格化错误
; 2 ZE 被零除错误
; 3 OE 溢出错误
; 4 UE 下溢错误
; 5 PE 精度错误
; 6 DAZ 非规格化浮点数置零
; 7 IM 无效的操作掩码
; 8 DM 非规格化操作掩码
; 9 ZM 被零除掩码
; 10 OM 溢出掩码
; 11 UM 下溢掩码
; 12 PM 精度掩码
; 13 RC 舍入控制
; 15 FZ 下溢则零
;
; 0到5是检测浮点异常,7到12是掩码,字位置1时,跳入异常程序(书中没写明显同,异常程序由链表指针地址控制,如SEH)
; 13到14会引发SIMD浮点异常。使用2位控制4舍5入。
; 00 四舍五入到最接近
; 01 向下取整 
; 10  向上取整 
; 11 截断

; 编译环境:
;   ld64 print_mxcsr.c
;   ld64 print_hex.c
;   includelib libc.lib (libc.lib 是lcc64下的64位库)
;   nasm -fwin64 01.asm
;   lclnk64 01.obj print_hex.obj print_mxcsr.obj

extern printf
extern print_mxcsr
extern print_hex
section .data
	eleven 		dq 11.0
	two			dq 2.0
	three		dq 3.0
	ten 		dq 10.0
	zero		dq 0.0
	hex			db "0x",0
	fmt1		db 10,"Divide,default mxcsr:",10,0
	fmt2		db 10,"Divide by zero, default mxcsr:",10,0
	fmt4		db 10,"Divide, round up:",10,0
	fmt5		db 10,"Divide,round dowm:",10,0
	fmt6		db 10,"Divide,truncate:",10,0
	f_div		db "%.1f divided by %.1f is %.16f, in hex:",0
	f_before 	db 10,"mxcsr before:",9,0
	f_after 	db "mxcsr after:",9,0
	
; mxcsr 值
	default_mxcsr	dd 00011111100000000b
	round_nearest	dd 00011111100000000b
	round_down 		dd 00111111100000000b
	round_up		dd 01011111100000000b
	truncate		dd 01111111100000000b

section .bss
	mxcsr_before 	resd 1
	mxcsr_after		resd 1
	xmm				resq 1

section .text
	global main
main:
	push 	rbp
	mov 	rbp,rsp

; 除法
; 默认 mxcsr
	mov 	rdi,fmt1
	mov 	rsi,ten
	mov 	rdx,two
	mov 	ecx, [default_mxcsr]
	call 	apply_mxcsr
;--------------------------------
; 除法(精度误差)
; 默认 mxcsr
	mov 	rdi,fmt1
	mov 	rsi,ten
	mov 	rdx,three
	mov 	ecx,[default_mxcsr]
	call 	apply_mxcsr
	
; 除以零
; 默认 mxcsr
	mov 	rdi,fmt2
	mov 	rsi,ten
	mov 	rdx,zero
	mov 	ecx,[default_mxcsr]
	call 	apply_mxcsr
	
; 除法(精度误差)
; 向上取整
	mov 	rdi,fmt4
	mov 	rsi,ten
	mov 	rdx,three
	mov 	ecx,[round_up]
	call 	apply_mxcsr
	
; 除法(精度误差)
; 向上取整
	mov 	rdi,fmt5
	mov 	rsi,ten
	mov 	rdx,three
	mov 	ecx,[round_down]
	call 	apply_mxcsr
	
; 除法(精度误差)
; 截断
	mov 	rdi,fmt6
	mov 	rsi,eleven
	mov 	rdx,three
	mov 	ecx,[default_mxcsr]
	call 	apply_mxcsr

	
; 除法(精度误差)
; 向上取整
	mov 	rdi,fmt4
	mov 	rsi,eleven
	mov 	rdx,three
	mov 	ecx,[round_up]
	call 	apply_mxcsr

; 除法(精度误差)
; 向上取整
	mov 	rdi,fmt5
	mov 	rsi,eleven
	mov 	rdx,three
	mov 	ecx,[round_down]
	call 	apply_mxcsr

; 除法(精度误差)
; 截断
	mov 	rdi,fmt6
	mov 	rsi,eleven
	mov 	rdx,three
	mov 	ecx,[truncate]
	call 	apply_mxcsr

	leave
	ret

; 函数 -----------------------------
apply_mxcsr:
	push 	rbp
	mov 	rbp,rsp

	push 	rsi
	push 	rdx
	push 	rcx
	push 	rbp	; 另一个用于堆栈对齐
	call 	printf
	pop 	rbp
	pop 	rcx
	pop 	rdx
	pop 	rsi
	
	mov 	[mxcsr_before],ecx
	ldmxcsr [mxcsr_before]
	movsd	xmm2,[rsi]
	divsd	xmm2,[rdx]
	stmxcsr	[mxcsr_after]
	movsd	[xmm],xmm2
	mov 	rdi,f_div
	movsd	xmm0,[rsi]
	movsd	xmm1,[rdx]
	call 	printf
	call 	print_xmm
; 打印 mxcsr
	mov 	rdi,f_before
	call	printf
	mov		rdi,[mxcsr_before]
	call 	print_mxcsr
	mov 	rdi,f_after
	call 	printf
	mov 	rdi,[mxcsr_after]
	call	print_mxcsr
	
	leave
	ret

; 函数 -----------------------------
print_xmm:
	push 	rbp
	mov		rdi,hex
	call	printf
	mov 	rcx,8

.loop:
	xor		rdi,rdi
	mov 	dil,[xmm+rcx-1]
	push 	rcx
	call 	print_hex
	pop 	rcx
	loop	.loop
	
	leave
	ret	

函数:

print_hex.c

print_mxcsr.c

// print_hex.c

#include <stdio.h>

void print_hex(unsigned char n){
	if (n < 16) printf("0");
	printf("x",n);
}
// print_mxcsr.c

#include <stdio.h>

void print_mxcsr (long int n){
	long int s,c;
	for (c = 15; c >= 0; c--)
	{
		s = n >> c;
		// 每 8 位后的空间
		if ((c+1) % 4 == 0) printf(" ");
		if (s & 1)
			printf("1");
		else
			printf("0");
	}
	printf("\n");
}

1.jpg

相关文章

随手写的时间设置程序,主要是防止系统时间无故修改。

随手写的时间设置程序,主要是防止系统时间无故修改。

程序说明:测试版程序功能。同步系统时间数据可选月历,手工输入可自动识别时间修改,修改后一分钟报警。测试版没有恢复时间功能。以后会增加。欢迎下载的朋友帮助我找程序问题,没有花多少功夫,请多多原谅。这个程...

阿里云后台的一个身份证信息查询工具。

阿里云后台的一个身份证信息查询工具。

注:此软件时效性已过,只在此陈列,没有什么意义。工具主图形界面有时会欠费,查不了时,请付1分钱给阿里云。下载地址:个人身份证阿里云查询.rar...

关于ch341驱动,联动3D打印机USB串口通讯.

关于ch341驱动,联动3D打印机USB串口通讯.

手上有个3D打印机,搬家的原因,好久没用.天气热了,打印温度很适合,正好可以使用.又过了一年.发现linux 版本内核已经升级,和原来的系统不一样了. 按照3D打印机的说明,和寻找它的程序,原来的方法...

关于编译器不愿意说的那些事。

关于编译器不愿意说的那些事。

计算机发展了好多年。当中也不泛有很多对程序的爱好。很多人不是专业水平,也不是在算法类中特别出众,就是喜欢而已。好像认为自己就只那个水平,或者为一些调试不通过发愁。可以说,实际上都不是你的错,是编译器的...

谈谈引导程序的想法。

谈谈引导程序的想法。

当个人电脑一出现就有了磁盘系统,不管是软盘,光盘,硬盘,计算机要应用操作系统就要引导,引导程序一段代码。这引导代码很小,在第一个磁盘的扇区上,平时没什么人注意它。这段代码损坏一个字节,都会造成计算机瘫...

masm32v12编译器自带库masm32.lib在nasm中的使用。

masm32v12编译器自带库masm32.lib在nasm中的使用。

修改了masm32.inc文件在nasm中使用。;╔═══════════════════════════════╗ ;║                       MASM32 库改nasm  ...