使用汇编器(NASM 32位)在IEEE 784上输入和处理浮点数 [英] Entering and dealing with floating point numbers on IEEE 784 with assembler (NASM 32bit)

查看:254
本文介绍了使用汇编器(NASM 32位)在IEEE 784上输入和处理浮点数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在大学攻读计算机体系结构专业,我被分配去编程一个工具,该工具将浮点数作为输入,我想将其存储在存储器中并以IEEE 784标准中数字的二进制表示形式的十六进制打印输出.

I am taking Computer Architecture subject at University, and I was assigned to program a tool which would take floating point number as input, I guess store it in memory and printout hexadecimal form of the binary representation of the number in IEEE 784 standart.

现在我对纸上的IEEE 784中的将十进制浮点数转换为二进制格式的算法充满信心,但我仍在努力为汇编程序提出解决方案(数字可以是-157.4、0.5,-0.6等).

Now I am certain about the algorithm of converting any decimal floating point number to its binary form in IEEE 784 on paper yet I struggle to come up with a solution for assembler (numbers can be such as -157.4, 0.5, -0.6 and etc.).

我的猜测是,我需要使用ASCII码和字符串操作从输入中提取符号,指数和尾数,然后将0或1存储在该符号的内存中,然后将转换为.以二进制形式进行符号运算,然后向右或向左移动位,直到得到一个数字,存储程序必须向右移动的次数(那个和+127将是指数,对吗?).然后我应该以某种方式处理输入数字的其余部分(.之后).我应该将其乘以2,就像在纸上一样,还是有解决此类问题的方法?最后,该程序应将每个4位转换为十六进制,但是我不确定如何.

My guesses are that I would need to extract the sign, the exponent and mantissa from input using ASCII codes and string manipulation and store either 0 or 1 in memory for the sign, convert what's before the . sign to binary form and shift bits right or left till I get one number, storing the amount of times the program had to shift right (that and +127 would be exponent, right?). Then somehow I should deal with the remaining part of the entered numbers (after . ). Should I multiply it by two, like on paper, or is there a method for this sort of problem? Lastly, the program should convert each 4bits to hex, but I am not sure how.

我不想复制-粘贴解决方案,我正在寻求学习汇编程序,以了解内部流程,而不仅仅是完成任务.如果有人曾经处理过此类问题,那我应该先去哪里.我应该学习什么?我有将近三个星期的时间来完成这项工作.

I don't want copy - paste solutions, I am seeking to learn assembler, to understand inner processes, not just finish the assignments. If anyone has ever dealt with such problems, where should I go first. What should I study? I have nearly three weeks for the task.

(最后一位-emu8086和NASM都应能够汇编程序).

(last bit - both emu8086 and NASM should be able to assemble the program).

谢谢!

推荐答案

您要同时提出两个问题.

You're asking two questions in one.

  1. 如何将字符串转换为IEEE-754浮点数?好吧,有趣的问题,而且比您预期的要复杂.要使最后一位正确舍入,还需要大量工作.

  1. How to convert a string to an IEEE-754 float? Ok, interesting question, and more complicated than you might expect. Getting even the very last bit rounded correctly requires a lot of work.

如何在x86 asm中执行此操作?愚蠢的问题;用与您在asm中编码任何算法相同的方式.最简单的答案是用C编写它,然后查看编译器输出. x87 FPU已过时,其中有一些指令会使用FP值执行按位操作,但SSE等普通FPU则没有. SSE可以进行整数转换,也可以进行常规的数学运算. (当然,您可以在同一寄存器上使用向量整数运算).无论如何,如果您还没有正确的算法并尝试实现它,那么我如何在asm中编写代码"就不是一个有趣的问题.

How do I do this in x86 asm? Silly question; the same way you code any algorithm in asm. The simplest answer to this is to write it in C, and look at the compiler output. The obsolete x87 FPU has some instructions that do sort of bitwise things with FP values, but normal FPUs like SSE don't have that. SSE just has conversion to/from integers, and normal math ops. (And of course you can use vector-integer ops on the same registers). Anyway, "how do I write this in asm" is not an interesting question if you don't already have a correct algorithm and an attempt at implementing it.


在线IEEE-754计算器建议查看libc源代码以获取将字符串转换为浮点数,反之亦然.


An online IEEE-754 calculator recommends looking at the libc source code for converting strings to floats and vice versa.

我发现对GNU libc的strtof/strtod进行了很好的撰写和分析函数,还将其与 David Gray的实现进行比较在Python,PHP,Java和一些Web浏览器中使用.

I found a nice writeup and analysis of GNU libc's strtof/strtod functions, which also compares it to David Gray's implementation which is used in Python, PHP, Java, and several web browsers, among other things.

快速摘要:

  1. 将十进制字符串解析为整数和小数部分.

  1. Parse the decimal string into integer and fractional parts.

将这些部分分别转换为二进制,转换为扩展精度整数(使用gmp例程).

Convert those parts to binary separately, to extended-precision integers (using gmp routines).

如果整数部分的有效位足以填充尾数,则无需查看小数部分.否则,请从小数部分获取位.

If the integer part has enough significant bits to fill the mantissa, you don't have to look at the fractional part. Otherwise, get bits from the fractional part.

小数部分很棘手:它可以有前导零,所以用小数表示.例如.00123 = 123/10 5 .通过扩展精度整数除法可以从此分数中得出所需的尾数位数,通常只使用一对div指令,而不是计算并丢弃大部分完整的扩展精度除法结果.

The fractional part is tricky: it can have leading zeros, so it's represented as a fraction. e.g. .00123 = 123/105. Getting the required number of bits for the mantissa out of this fraction is done with extended-precision integer division, typically only using a couple div instructions rather than computing and throwing away most of the full extended-precision division result.

一旦有了32位浮点值,就可以将其打印为十六进制字符串,就像对任何32位整数一样. Base16非常方便,因为每8位映射到两个十六进制数字.在base10中打印整数通常需要重复除以10,直到数字< = 9,但在base16中只是将其位移了4.

Once you have a 32bit float value, you can print it as a hex string the same way as you would for any 32bit integer. Base16 is super convenient, because every 8 bits maps to two hex digits. Printing integers in base10 typically requires repeated division by 10 until the number is <= 9, but in base16 that's just a bit-shift by 4.

这篇关于使用汇编器(NASM 32位)在IEEE 784上输入和处理浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆