【问题标题】:Why sub eax, '0' for adding instead of just add? [duplicate]为什么 sub eax, '0' 用于添加而不是添加? [复制]
【发布时间】:2018-11-04 20:50:37
【问题描述】:

所以,我一直在尝试学习一些汇编,我看到了一个加法的例子,但我真的不明白一件事:

section .text
    global _start       
_start:                     
    mov eax, '3'
    sub eax, '0'
    mov ebx, '4'
    sub ebx, '0'
    add eax, ebx
    add eax, '0'
    mov [sum], eax
    mov ecx, msg
    mov edx, len
    mov ebx, 1
    mov eax, 4
    int 0x80
    mov ecx, sum
    mov edx, 1
    mov ebx, 1
    mov eax, 4
    int 0x80
    mov eax, 1
    int 0x80
section .data
msg db  'The sum is:',0xA, 0xD
len equ $ - msg 
segment .bss
sum resb

我明白除了sub eax, '0'之外的所有内容

我的意思是结果应该是 -7,因为当它执行 sub eax, '0' 时,它会反转数字...

【问题讨论】:

  • 请勿发布图片,但请发送代码。
  • 您认为mov eax,'3' 会做什么?它将eax 寄存器设置为值 51,这是字形“3”的 ASCII 码......并且要从中获得二进制整数值 3,您必须从中减去 48 (51-48=3)。 '0' 是值 48(查看 ASCII 表以了解不同的字母是如何由 ASCII 编码中的 7 位整数编码的)。所以该代码正在执行 (51-48) + (52-48) + 48 并且输出为 ASCII 字母。顺便说一句,代码包含错误,例如 mov [sum],eax 是错误的(它将新字母“7”写入内存,然后它用零覆盖接下来的 3 个字节......它应该是 mov [sum],al
  • 另外7-0 = 7,减去零不会反转值。从零中减去会反转值 (0-7 = -7)。因此,即使'0' 实际为零(不是,它是 48 或 0x30 或 0b00110000,或者您喜欢的任何格式,原作者确实更喜欢源中的“字符”引号格式),您的期望在逻辑级别上已经是错误的代码,即'0',汇编器将对其进行解析并将其编码为二进制机器代码为00110000)。
  • 但是 sub eax, '0' 将 eax 减为零并存储在 eax 中,至少我是这么读的
  • @Deketh 没有。我不确定您所说的“将 eax 减去零”是什么意思,我不是以英语为母语的人,但我认为您可以 from eax 或 eax from减去零> 零(在数学术语中,结果 = eax - 0,或结果 = 0 - eax)。第二个将用作“否定”指令,但在 8086..80586 上不可能使用整数数学,没有反向减法(可能在 MMX/SSE/AVX/... 扩展指令中,我从头上不知道那些)。使用 x87 FPU 协处理器,实际上 FP 数字的反向减法(fsubfsubr)。 '0' 是 48(非零)。

标签: assembly addition subtraction instructions


【解决方案1】:

... 因为当它执行 sub eax, '0' 时,它会反转 num

减法sub eax, '0'AL中的字符转换为对应的数字 0-9。仅此而已。

应该是这样写的:

sub al, '0'

指令add al, '0' 将以同样的方式将AL 中的数字(范围0-9)转换为准备输出的字符。


我的意思是结果应该是-7

如果你运行程序,你会看到输出是一个正数 7。

【讨论】:

  • so, mov al, '0' 把字符变成数字了?
猜你喜欢
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 2013-09-09
  • 1970-01-01
相关资源
最近更新 更多