问题描述
最近我在这里问了一个问题,但没有正确提问。我已经阅读了很多,但我仍然没有完全理解一些东西,但是从一开始:
我收到了用程序集 (.COM) 编写的程序代码。将两个整数相加。两个数字都必须在 [-32768..32767] 范围内。这两个数字都必须在 U2 代码中从字符转换为 16 位形式。但是,此加法的结果必须是 32 位的,也在 U2 中(使用 32 位寄存器)。
这段代码有将近 150 行,所以我可能只包含这段代码的一部分。我必须很好地理解每一行。我可以描述其中的大部分,但仍然不能完全理解某些行。 (我不明白的行以粗体显示)
首先:
.386p
.MODEL TINY
Code SEGMENT USE16
ORG 100h
.
Sign db 0
.
Start:
**mov byte ptr [Sign],0** ;Do I understand correctly that we set the high bit to 0 here? As positive by default
xor ax,ax
push ax
;here (Adding: ) I understand everything,addition of 2 numbers is done and some conditions
Adding:
pop ax ;second number
pop bx ;first number
add ax,bx ;adding
jo Overflow_Flag
js Sign_Flag
jmp On_ASCII ;convert to ASCII
But I don't understand this following thing. When the result of this addition is negative,we "jump" to the Sing_Flag label and ...
Sign_Flag :
**mov ebx,0ffff0000h** ;Why are we writing mov ebx,0ffff0000h here?
add ebx,eax ;further I understand
neg ebx
mov dl,'-'
mov ah,02h
int 21h
mov eax,ebx
jmp On_ASCII
我想介绍一下我的理解:
FFFF0000h = 1111 1111 1111 1111 0000 0000 0000 0000
通过这一行,我们将 16 位值扩展为 32 位形式。
比如这个加法的结果是:-5,所以:
5 = 0101 (BIN)
NEG(0101) + 1 = 1010 + 1 = 1011 = -5 (DEC)
所以在这种情况下:
0000 0000 0000 0000 1111 1111 111 1011 (neg ebx)
这就是我不明白/找不到信息的地方:
- 为什么是 0ffff0000h 而不是例如000000000h?这四个 1 是做什么用的?
- 汇编器如何知道数字的“结尾”在哪里?我们有 1111 1111 1111 1011,为什么它不计算下一个 1?
- 我理解 mov byte ptr [Sign],0 吗?
谢谢!
解决方法
第一条粗线将变量 Sign
初始化为零。在您提供的代码片段中不再使用它,因此很难说它的用途。
mov ebx,0ffff0000h** ;Why are we writing mov ebx,0ffff0000h here?
add ebx,eax ;further I understand
neg ebx
这是如何从 EBX
加载具有绝对值的 AX
的不寻常方式。 (我会使用 MOVSX EBX,AX
)。如果 AX
中的加法结果为负(-5),则跳转到 Sign_Flag:
,在 EAX
的上半部分带有未定义的垃圾。假设它在添加之前被清除,然后 EAX=0000_FFFBh
,将它添加到 EBX=0FFFF_0000h
,现在您有 EBX=0FFFF_FFFBh
,即 -5。在 NEG EBX
之后,它给出 EBX=0000_0005h
,它将(连同 DL 中的减号)通过 On_ASCII
在输出上发送。