【发布时间】: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 数字的反向减法(
fsub与fsubr)。'0'是 48(非零)。
标签: assembly addition subtraction instructions