将 32 位文件大小与 16 位用户输入进行比较?
Comparing a 32 bit file size to 16 bit user input?
我正在编写一个汇编程序,它分析文件并将它们的信息(名称和大小)输出到文件中。我基本上使用 4Eh 和 4Eh 中断来搜索文件:它们都是 return DTA 对象,其中包含关于该文件的相应信息。
它 return 是一个 32 位文件大小,我必须将其与用户输入的 16 位大小进行比较(如果它大于给定的 - 用户输入 - 大小,我必须只输出文件信息)。
这里明显的问题是我不知道如何将 32 位数字转换为 16 位数字,否则我无法比较它们。也许有人知道如何执行此转换或对如何执行此比较有任何其他想法?
如果可能的话,也许有人可以提供 TASM Intel x86 汇编中的示例代码
你在倒着想。
你想zero-extend把16位的数变成32,再做32位的比较。 (在 C 语言中,对不同类型的操作提升到一个足够宽的类型来容纳它们,因为这几乎总是您想要的。)
正如 Jester 解释的那样,这意味着用户输入的高 16 位始终为零,因此 extended-precision / BigInteger 比较的上半部分只是检查文件大小的上半部分 non-zero。然后,如果文件大小足够小,可能低于 16 位用户输入,则将低半部分与阈值进行比较。
您还可以通过 执行 extended-precision 减法 :
仅使用一条分支指令来检查 less-than
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
这很好而且紧凑,但可能并不比 cmp/jz
和 cmp/jb
特别好,尤其是当 32 位数字在内存中时。 (您不想将 sbb
与内存目标一起使用;那样效率较低。)
转换 32->16 很简单:只需忽略高 16 位即可截断。但你似乎已经意识到那不会如你所愿。
回答您的旧标题:将 dx:ax 中的 32 位整数转换为 cx 中的 16 位整数,请使用此指令:mov cx, ax
.
我正在编写一个汇编程序,它分析文件并将它们的信息(名称和大小)输出到文件中。我基本上使用 4Eh 和 4Eh 中断来搜索文件:它们都是 return DTA 对象,其中包含关于该文件的相应信息。
它 return 是一个 32 位文件大小,我必须将其与用户输入的 16 位大小进行比较(如果它大于给定的 - 用户输入 - 大小,我必须只输出文件信息)。
这里明显的问题是我不知道如何将 32 位数字转换为 16 位数字,否则我无法比较它们。也许有人知道如何执行此转换或对如何执行此比较有任何其他想法?
如果可能的话,也许有人可以提供 TASM Intel x86 汇编中的示例代码
你在倒着想。
你想zero-extend把16位的数变成32,再做32位的比较。 (在 C 语言中,对不同类型的操作提升到一个足够宽的类型来容纳它们,因为这几乎总是您想要的。)
正如 Jester 解释的那样,这意味着用户输入的高 16 位始终为零,因此 extended-precision / BigInteger 比较的上半部分只是检查文件大小的上半部分 non-zero。然后,如果文件大小足够小,可能低于 16 位用户输入,则将低半部分与阈值进行比较。
您还可以通过 执行 extended-precision 减法 :
仅使用一条分支指令来检查 less-thanfile_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
这很好而且紧凑,但可能并不比 cmp/jz
和 cmp/jb
特别好,尤其是当 32 位数字在内存中时。 (您不想将 sbb
与内存目标一起使用;那样效率较低。)
转换 32->16 很简单:只需忽略高 16 位即可截断。但你似乎已经意识到那不会如你所愿。
回答您的旧标题:将 dx:ax 中的 32 位整数转换为 cx 中的 16 位整数,请使用此指令:mov cx, ax
.