装配(NASM)如何进行数值运算

时间:2012-11-28 00:35:35

标签: assembly x86 numbers character nasm

我在java中编写了很多程序并且了解了python的基础知识,有时我使用c ++ ... 这些都是高级编程语言,它们很棒,除了我很好奇在这种情况下汇编语言在更深层次上的工作方式...我开始学习x86处理器的汇编并选择NASM作为我的汇编语言。 我花了一些时间来学习寄存器和堆栈如何工作,如何存储信息以及如何更改信息,不仅仅是阅读而是练习,使用调试器等等,这些事情真的开始困扰我: 数值运算......

我的意思是每当从输入中读取某些内容时,它都会作为相应的ASCII值存储在内存中,我很好用...我理解如何通过整个传递读取和写入控制台的基础知识然而,如前所述,包括数字在内的字符存储为ASCII值.0存储为0x30,1存储为0x31等...这意味着单个数字存储为整个字节,我将其视为一个缺点,因为我知道一个字节可以表示最多255的数字,这将节省大量的内存和时间来进行数学运算并为其他数据留出空间......在像c ++这样的语言中,整数值仅由4个字节表示,这意味着这些语言可以存储最多4294967295的整数

达到目的...... 我真正想知道的是什么是表示数字和使用nasm进行基本算术运算的最佳方法..我应该将这些数字保留为ASCII值并在字节级别上执行操作,还是应该转换这些数字以便字节可以持有更大的价值?或者有没有办法更有效地读取数字?

PS:很抱歉这篇长篇文章,我只是想了解一下我关注的整体背景,以便你们可以帮助我找到它...而对于糟糕的英语...我试着像我一样清楚我可以(英语不是我的母语,但我尽可能多地理解它...当我编程时,它对英语很有帮助)

4 个答案:

答案 0 :(得分:0)

我会从ASCII转换。它使一切变得更简单,想象乘以ascii数字。如果你使用ascii有多个数字可能会变得非常烦人。此外,您可以声明多个字节的变量:

  

b = byte

     

w = word(2个字节)

     

dw =双字(4字节)

var1 w   0000h ;
var2 dw   0007h
var3 b 0000h

这样您就可以从控制台获取输入。只需一位数:

mov ah, 1  ;int 21h (interrupt 21h) in the next line is a function that can do many things
int 21h    ;depending on the value you put in register "ah". Using 1 it reads input the value is stored in "al"
add al, -48 ;ascii -> bin .. here you substract 48 to transform from ASCII
mov [var1],al

你可以添加两个这样的数字(你需要一些额外的负数) 你会得到

[VAR1] = [VAR1] + [VAR2]

mov al,[var2]
add al, [var1]
mov [var1],al

CPU通常还有用于乘法的指令

检查一下,它是8086处理器的指令集,这是你可以告诉它做的所有事情。 8086 Instruction set

答案 1 :(得分:0)

与任何语言一样:如果您有一个字符串,但想要对其进行数值运算,请将其转换为数字。除非它不适合您的处理器的任何通用寄存器。

我现在不是你要针对的指令集,但是例如。在x86-64中,有8位,16位,32位和64位通用寄存器来保存您的数字。如果你的数字不适合64位(在x86-64中),那么事情可能会变得更复杂一些。如果您想要在目标架构中提供最大范围的数字,最好的方法是将数字存储在最大可能的寄存器或内存中。

与高级语言相比,在汇编级别中,有符号和无符号变量之间没有区别,它只取决于您如何处理它。但是有签名和无符号操作,例如有符号乘法(imul),有符号除法(idiv),无符号乘法(mul),无符号除法(div)。

答案 2 :(得分:0)

首先,你不能......我再说一遍,你无法将汇编语言与任何高级语言进行比较!他们如何存储和与数据交互是完全不同的。他们这样做是为了让程序员的生活更轻松。如果要将char的ASCII代码存储为DWORD,请继续。

在大会中,绝对没有手握。 CPU不知道你想对任何数据做什么,无论是文件中的字节还是键盘上输入的字符。

你在大会中自己做所有事情。您在键盘上按下的字符是ASCII,因为这是您键入时显示的内容,如果您想对它们执行其他操作,程序员可以根据需要对其进行转换。

将ASCII编号转换为数字非常简单。

Numbers: 0  1  2  3  4  5  6  7  8  9
ASCII:   48 49 50 51 52 53 54 55 56 57

看到它们之间的区别? 48是神奇的数字。

循环遍历字符串,测试每个数字以查看是否在48到57之间,其他任何内容都会跳过。如果ASCII字符在48到57之间,则从字符中减去48并且您有一个数字。添加48以获取该数字的ASCII字符。

没有告诉你使用atodw / atoi或其他什么,你通过自己学习更多,而且并不难。

答案 3 :(得分:-2)

Ascii字符不是数字。

您需要使用 atoi 功能。