송영조
송영조

Reputation: 71

assembly Move File Pointer

enter image description here

How to calculate CX:DX value? I don't know what that means somebody help me

Upvotes: 0

Views: 1021

Answers (1)

Ped7g
Ped7g

Reputation: 16606

File pointer is address into the file content. If you have bitmap image, and you know in code the pixel data start at offset 540, and you want to skip reading the header, you open the file, and then you set the file pointer to offset 540, and then you read the pixel data...

16 bits can hold 216 = 65536 different combinations of bits set to 0 or 1.

So a common way to interpret 16 bits as unsigned integer values is by treating i-th bit as i-th power of two value, i.e. "b0" has value 20 = 1, "b10" has value 210 = 1024, etc... By this kind of interpretation a 16 bit value can cover all unsigned integers from 0 to 65535.

Now if you have some large file, like 1MB ... well, that used to be large file in 1980, really, not to be seen regularly, of course today it's the other way, you will have probably small trouble to find file with size under 65536... that 1MB does not fit into 16 bits. So if you want to "glide" the file pointer along its content, you need more bits to specify where you want the file pointer to point to.

Combining two 16 bit registers together gives you 32 bit values, that can have 232 = 4294967296 = 4Gi different states. Now this will cover files up to 4GiB size, which was more than the whole hard disk size (80MiB disks were common). So if you are around 198x designing file system, with storage devices in tens of megabytes and files in kilobytes, having 32 bit file pointer sounds like future-proof design, at least for half a century.

And that's it. cx:dx in this context is single 32 bit value, cx holds the upper 16 bits, i.e. "b16" to "b31", dx hold the lower 16 bits "b0" to "b15". To reconstruct the value in decimal you can do cx * 65536 + dx (*65536, because that's the number of all possible values in dx, after that is exhausted during incrementing, you increment cx by one, and go again through whole dx for next 65536 values).

In binary you don't need to multiply anything, just use it as upper/lower bits of large value, i.e. to add two offsets ax:bx + cx:dx you can use code like this:

add dx,bx   ; adding low 16bit parts
            ; (will set carry flag in case of overflow)
adc cx,ax   ; adding high 16bit parts + CF
; here cx:dx is equal to the 32b addition result

Note: don't mistake this 32 bit value math with the 16b real mode addressing consisting of segment:offset, while that does use two 16 bit values too to describe physical memory address, they are combined in special way phys_adr = segment * 16 + offset to cover only 20 bit address space (1MiB of memory did look like insanely large, believe it or not :) ), but with different overlapping possibilities. So when segment registers like es, ds, cs, ss, ... are involved, it's very likely about memory address calculation, not full 32 bit values composed from two 16 bit values.

Upvotes: 1

Related Questions