I'm writing an assembler program, which analyzes files and outputs their information ( name and size ) to the file. I'm basically using 4Eh and 4Eh interrupts to search for files : they both return DTA object with according information about that file in it.
It returns a 32-bit filesize which I have to compare with a 16-bit user inputted size (I have to only output files information if it's larger than the given - user inputted - size).
The obvious problem here is that I don't know how to convert a 32 bit number into a 16 bit number, because otherwise I can't compare them. Maybe someone knows how to perform this conversion or has any other ideas on how to implement this comparison ?
If possible, maybe someone could provide an example code in TASM Intel x86 assembly
You're thinking about it backwards.
You want to zero-extend the 16-bit number to 32, and do a 32-bit comparison. (In C, operations on different types promote to a type that's wide enough to hold them both, because that's almost always what you want.)
As Jester explains, this means the upper 16 of your user input is always zero, so doing the upper half of the extended-precision / BigInteger comparison is simply checking that the upper half of the file size for non-zero. Then, if the file size is small enough that it might be below a 16-bit user input, compare the low half with the threshold.
You can also check for less-than with only one branch instruction by doing an extended-precision subtract:
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
This is nice and compact, but probably not particularly better than cmp/jz
and cmp/jb
, especially if the 32-bit number is in memory. (You don't want to use sbb
with a memory destination; that's less efficient.)
Converting 32->16 is trivial: just truncate by ignoring the upper 16 bits. But you seem to have already realized that wouldn't do what you want.
To answer your old title: to convert a 32-bit integer in dx:ax to a 16-bit integer in cx, use this instruction: mov cx, ax
.