I have two number arrays to be printed to a file. If I use SI and BP as the pointers to the
arrays, and DI as the pointer to the buffer, no problem. But if I use BP as the buffer
pointer, and SI and DI as the two array pointers, nothing is printed. The buffer exists
after I've loaded it, as I have confirmed on the screen, but it won't print to file.
Is there some constraint on using BP that I've overlooked?
Thanks for your advice/comments.
Michael
With so little information it's impossible to know what the problem might be. Given a valid file handle in BX, a valid buffer address in DS:DX, a valid byte count in CX, and assuming that the file is accessible, the Write File or Device function should succeed in writing to the file. If the function is returning with the carry flag set, then the function failed and AX should contain an error code.
How are you using BP? Don't forget that without a segment override, the byte (or whatever) at [BP] is actually at SS:[BP], not DS:[BP].
Quote from: MichaelW on June 21, 2008, 06:09:49 AM
With so little information it's impossible to know what the problem might be.
Agreed - post a bit of code, then we can try and help you without resorting to reading your mind. :lol
Thanks for the answers to my question. I was using BP in an efort to minimize the number of lines
in the code. (If I use DI for one of my data arrays and also for the buffer, there will have to be
some PUSHing and POPping - and some additional ofset adjustments - while transferring each number
pair to the buffer.)
I will check into the segment override scenario. If BP is defined with respect to SS,
not DS, then I don't understand why I was able to verify the status of the buffer using a few lines
of (diagnostic) code to show the data on the screen, without the segment override you referred to.
Thanks for your help.
Michael
Quote from: carlottagp on June 21, 2008, 11:28:08 AM... using a few lines of (diagnostic) code ...
So what code? Help us out, we can help you too.
Quote from: carlottagp on June 21, 2008, 11:28:08 AM
If BP is defined with respect to SS, not DS, then I don't understand why I was able to verify the status of the buffer using a few lines of (diagnostic) code to show the data on the screen, without the segment override you referred to.
Indirect memory operands that specify BP cause the instruction to use SS instead of DS, the default segment for most instructions that access memory. For the TINY memory model or code that uses the .STARTUP directive, this distinction does not matter because SS==DS.
"... using a few lines of (diagnostic) code ...
So what code? Help us out, we can help you too."
I have a simple subroutine which shows BX on the screen, so I just copied each byte of the buffer to BL and
called the subroutine.
Rather than getting into a "segment override", which I'm afraid I don't understand, can I use BX for the index of the
buffer, rather than BP?
Thanks again,
Michael
Some instructions 'assume' a segment register
- lods assumes DS:SI
- stos assumes ES:DI
- mov [sp],x / mov x,[sp] assumes SS:SP
- mov [bp],x / mov x,[bp] assumes SS:BP
So code like 'mov ax,[bp]' looks to the CPU as 'mov ax,ss:[bp]'. This isn't a problem with a .com file, because (unless you change segment registers) DS=SS,
which means SS:BP is (coincidentally) DS:BP. In a .exe file, there is usually a seperate stack, which means SS is not the same as DS. In that case, you need to override
the assumed segment register (SS) with 'mov ax,ds:[bp]'.
Using BX,SI and DI 'assumes' that it's DS - it's only BP that assumes SS.
For an EXE you can use the .startup directive, or equivalent code.
.startup
0000 *@Startup:
0000 B8 ---- R * mov ax, DGROUP
0003 8E D8 * mov ds, ax
0005 8C D3 * mov bx, ss
0007 2B D8 * sub bx, ax
0009 C1 E3 04 * shl bx, 004h
000C 8E D0 * mov ss, ax
000E 03 E3 * add sp, bx
This effectively moves the stack to the end of DGROUP by setting DS and SS to DGROUP and adding the size of the data segment, in bytes, to SP.