Assembly 比较32位文件大小和16位用户输入?

Assembly 比较32位文件大小和16位用户输入?,assembly,x86,tasm,Assembly,X86,Tasm,我正在编写一个汇编程序,它分析文件并将其信息(名称和大小)输出到文件中。我基本上是使用4Eh和4Eh中断来搜索文件:它们都返回DTA对象,其中包含关于该文件的相应信息 它返回一个32位文件大小,我必须将其与16位用户输入的大小进行比较(如果它大于给定的-用户输入的-大小,我必须只输出文件信息) 这里明显的问题是,我不知道如何将32位数字转换为16位数字,因为否则我无法比较它们。也许有人知道如何执行此转换,或者对如何实现此比较有其他想法 如果可能的话,也许有人可以在TASM英特尔x86汇编中提供一

我正在编写一个汇编程序,它分析文件并将其信息(名称和大小)输出到文件中。我基本上是使用4Eh和4Eh中断来搜索文件:它们都返回DTA对象,其中包含关于该文件的相应信息

它返回一个32位文件大小,我必须将其与16位用户输入的大小进行比较(如果它大于给定的-用户输入的-大小,我必须只输出文件信息)

这里明显的问题是,我不知道如何将32位数字转换为16位数字,因为否则我无法比较它们。也许有人知道如何执行此转换,或者对如何实现此比较有其他想法


如果可能的话,也许有人可以在TASM英特尔x86汇编中提供一个示例代码

您正在逆向思考

您希望将16位数字的零扩展为32位,并进行32位比较。(在C语言中,对不同类型的操作提升到一个足够宽的类型,可以容纳这两种类型,因为这几乎总是您想要的。)

正如Jester所解释的,这意味着用户输入的上16始终为零,因此进行扩展精度/BigInteger比较的上半部分只是检查文件大小的上半部分是否为非零。然后,如果文件大小足够小,可能低于16位用户输入,请将低一半与阈值进行比较


您还可以通过执行扩展精度减法,仅使用一条分支指令检查小于:

file_loop:               ; do {
    load a new file size

    ;; file size in dx:ax,  threshold in cx
    cmp    ax, cx        ; low half (non-destructive: cmp = sub but without writing ax)
    sbb    dx, 0         ; high half. (destructive)
    ; ZF reflects only the high-half compare result
    ; CF is useful (and so are SF/OF for signed compare).
    ; Avoid JCC conditions that depend on ZF, like JA.
    jnb   file_loop    ; } while(CF==0);   (JNB = JNC)

;;; dx:ax < 0:cx unsigned was true.
;;; So we know the original DX was 0 (and is now 0xFFFF)
;;; AX = the file size (which we didn't destroy), and we know it fits in 16 bits.

    do something with this file
    jmp  file_loop
文件_循环:;做{
加载新的文件大小
;文件大小(dx:ax),阈值(cx)
cmp ax,cx;下半部分(非破坏性:cmp=sub,但不写入ax)
sbb dx,0;高半(破坏性)
;ZF仅反映高半比较结果
;CF是有用的(SF/OF对于符号比较也是有用的)。
;避免依赖ZF的JCC条件,如JA。
jnb文件_loop;}while(CF==0);(JNB=JNC)
;;; dx:ax<0:cx unsigned为true。
;;; 所以我们知道原来的DX是0(现在是0xFFFF)
;;; AX=文件大小(我们没有销毁),我们知道它适合16位。
对这个文件做些什么
jmp文件循环
这很好而且紧凑,但可能并不比
cmp/jz
cmp/jb
更好,特别是如果32位数字在内存中。(您不希望将
sbb
与内存目标一起使用;这样效率较低。)


转换32->16非常简单:只需忽略上面的16位来截断。但你似乎已经意识到这不是你想要的


要回答您的旧标题:要将dx:ax中的32位整数转换为cx中的16位整数,请使用以下说明:
mov-cx,ax

显然,如果文件大小的前16位不是零,则它比用户输入的数字大。如果它们为零,则有两个16位数字可供比较。简单。0..65535范围内的值将适合16位(高16位为零)。65536+值在高位16位中有一些非零位。如果你的应用程序只接受16位值(0..65535)作为输入,那么你可以首先通过检查16位的上限来检查长度是否大于等于65536。这是否意味着,同样,我可以比较8位和32位的数字?我的意思是,如果我将32位数字分成4个8位数字(两个高部分,两个低部分),因此我可以假设,如果任何高部分或最左低部分中有任何非零数字,那么这个数字高于任何8位数字。否则,我可以将32位数字的最右下半部分与8位数字进行比较。@JonasPetraška:是的,但请注意,您仍然可以一步检查32位数字的上16位,因为8086是一种16位体系结构。您还可以
movzx
(386)或
xor ax,ax
/
mov al,single_byte
到零将8位数字扩展到16位,然后您可以对32位数字的下半部分进行16位比较。@PeterCorder:非常感谢@JonasPetraška还请记住(在检查内存中的单独字节时)x86是小端的,因此DTA中的文件大小很可能也在LE中,即大小66051在内存中存储为4字节
03 02 01 00
,因此最低的8位在偏移量+0处,最高的8位在+3地址处。。。i、 e.要从内存检查上16b是否为零:
xor ax,ax
cmp[dta\u fsize+2],ax
jnz size\u高于65535
mov ax[dta\u fsize];=低位16位(值0..65535)
。同样相关:您可以查看C编译器的输出(对于32位模式下的64位整数),查看它使用了什么指令。对于其他比较,如
==
,只需更改C源代码。