在Assembly 中将16 位值扩展为32 位形式以及有关U2 代码的问题

问题描述

最近我在这里问了一个问题,但没有正确提问。我已经阅读了很多,但我仍然没有完全理解一些东西,但是从一开始:
我收到了用程序集 (.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)
这就是我不明白/找不到信息的地方:

  1. 为什么是 0ffff0000h 而不是例如000000000h?这四个 1 是做什么用的?
  2. 汇编器如何知道数字的“结尾”在哪里?我们有 1111 1111 1111 1011,为什么它不计算下一个 1?
  3. 我理解 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 在输出上发送。