Hello all,
As an assembly programmer I never needed to write *big* programs, and therefore always used the "tiny" memory model where CS = DS = SS.
Though at some point I realized that not having SS equal to DS
creates its own problems - when trying to access stack-based data
(strings).
A "lea dx,[Stack-based item]" will work, but, for example, using it
with "mov ah,09h", "int 21h" will ofcourse fail, as DX is not
pointing into DS.
My question :
Does anyone know how this is solved ? Other than (manually!)
wrapping all such calls in a "push ds", "mov ax,ss", "mov ds,ax" ....
"pop ds" sequences I mean.
No, sorry. Why would I put strings in the stack space?
John,
No, sorry. Why would I put strings in the stack space?
Lol ! Go troll someone else, will you.
A "lea dx,[Stack-based item]" will work, but, for example, using it
with "mov ah,09h", "int 21h" will ofcourse fail, as DX is not
pointing into DS.
Lol ! Go troll someone else, will you.I'm sorry, it wasn't meant as a troll.
If ss<>ds then to load /dx/ with a saved string pointer
I'd use the 'pop' instruction.
I presume you're after something like /mov dx,[ss:stack+offset]/
John,
Lol ! Go troll someone else, will you.I'm sorry, it wasn't meant as a troll.
Phew ! Thank {deity} for that.
If ss<>ds then to load /dx/ with a saved string pointer
I'm sorry, are you /sure/ you aren't trolling ? Since when does
"lea" load something that was saved ?
I'd use the 'pop' instruction.
No you wouldn't.
I can ofcourse explain to you how "lea" works, but I always got the
idea you knew more about programming than I ever will. IOW, whats
going on here ?
I presume you're after something like /mov dx,[ss:stack+offset]/
Definitily not.
Hello all,
As an assembly programmer I never needed to write *big* programs, and therefore always used the "tiny" memory model where CS = DS = SS.
Though at some point I realized that not having SS equal to DS creates its own problems - when trying to access stack-based data (strings).
A "lea dx,[Stack-based item]" will work, but, for example, using it with
"mov ah,09h", "int 21h" will ofcourse fail, as DX is not pointing into DS.
My question :
Does anyone know how this is solved ? Other than (manually!) wrapping all such calls in a "push ds", "mov ax,ss", "mov ds,ax" .... "pop ds" sequences
I mean.
Regards,
Rudy Wieser
OTOH I rarely use /lea/.
OK I'll bow out, I'm clearly not understanding your requirement.
Than again, I think I painted myself in a corner. :-|
Although I was thinking of some code which would allocate a stack segment
and initialise SS:SP to it (causing SS to become different from DS), when I this morning looked at the different memory models Borlands Tasm offers I could only find one which /doesn't/ set up SS equal to DS. and that one, "TPASCAL", isn't even a standard one. I wonder why that is. :-)
Its like having 20/20 vision looking back. If only I had something like
that beforehand ...
As for general use... Is segment override not applicable? e.g.
I think that's it; the answer is "don't do that" (Sebastian!);
It still seems to me you were trying to use stack space to store strings.
John,
I think that's it; the answer is "don't do that" (Sebastian!);
:-) Yep. Not because it cannot work, but because it just costs too much work.
The thing is that I knew a way to deal with it (the wrapper code I mentioned in my first post), but wanted to know if there would be a simpler approach, making a SS <> DS setup feasable to use.
It still seems to me you were trying to use stack space to store strings.
:-) Not only trying, but have done so for quite a number of years now.
Are you trying to tell me that you have never used procedure-local variables ?
Are you trying to tell me that you have never used procedure-local
variables ?
Yes. I'm not the whizz programmer you thought I was!
Hello all,
As an assembly programmer I never needed to write *big* programs, and therefore always used the "tiny" memory model where CS = DS = SS.
Though at some point I realized that not having SS equal to DS creates its own problems - when trying to access stack-based data (strings).
A "lea dx,[Stack-based item]" will work, but, for example, using it with
"mov ah,09h", "int 21h" will ofcourse fail, as DX is not pointing into DS.
My question :
Does anyone know how this is solved ? Other than (manually!) wrapping all such calls in a "push ds", "mov ax,ss", "mov ds,ax" .... "pop ds" sequences
I mean.
Lastly, perhaps you should be using segmented memory or you could
generate code by some means other than the assembler and more higher
level.
I'd advise looking into some kind of macro assembly.
If your assembler can tell you where (in what segment) a variable
is allocated
(assuming it can actually allocate a variable on the stack just like in
the data segment)
and if the assembler can conditionally assemble code based on that,
then you can eliminate some unnecessary segment manipulation.
Lastly, perhaps you should be using segmented memory
or you could generate code by some means other than the
assembler and more higher level.
:-) I like Assembly because it /doesn't/ hide all kinds of stuff from me.
But nearly no PC can execute 16 bit code directly these days.
So what sense does it make to still write 16 bit code?
And 32 bit code also has the advantage, that you don't have to
mess around with segments.
But nearly no PC can execute 16 bit code directly these days.
For starters, why including a restriction like "directly" ? How does that matter ?
And for seconds, how does "nearly no PC" matter as long as mine does ?
So what sense does it make to still write 16 bit code?
What sense does it make for anyone to have a hobby ? Its a waste of time, not bringing any money on the table.
And 32 bit code also has the advantage, that you don't have to
mess around with segments.
True. But why "mess around" with it /at all/ ? I'm sure there are lots of well-payed professional programmers which can deliver much better quality in a much shorter time.
But a question : why are you (still?) in this newsgroup, which is all about an OS that has been obsolete for over 20 years and, listening to you, likely won't even be able to run on any of your computers ...
Alexei,
I'd advise looking into some kind of macro assembly.Borlands Tasm does support macros. But alas, they do not measure up to the inbuild method of calling procedures and its checking of the (ammount and type of) provided arguments.
If your assembler can tell you where (in what segment) a variableNope. That "lea dx,[bp-xxxx]" implicitily uses SS as its base. There is no way to tell by looking at DX itself.
is allocated
(assuming it can actually allocate a variable on the stack just like in<huh?> You're the second one who doubts that, even though procedure-local variables are a thing in most any language ...
the data segment)
and if the assembler can conditionally assemble code based on that,I'm not at all sure I can override build-in menemonics to execute a macro
then you can eliminate some unnecessary segment manipulation.
... Otherwise I would need to add pseudo(?) code around pretty-much everything.
Lastly, perhaps you should be using segmented memoryIsn't that what is what started my problem ? Putting DS into a different segment than SS ?
or you could generate code by some means other than the:-) I like Assembly because it /doesn't/ hide all kinds of stuff from me.
assembler and more higher level.
A program is written in order to be executed. To write a program
which can be executed on nearly none of the current computers
(without first installing additional software like DOSBox) doesn't
make much sense.
Because normally a program is not only executed once. And if the
code still can be useful in a few years, it shouldn't be written
for a system which is obsolete already now.
Even if done as a hobby, the result should be something useful.
I'm thinking more of declaring a symbol for each string and deducing
the segment from that symbol (or it maybe a pair of symbols, one
for the offset, the other for the segment).
I don't remember the details and they are important.
I'm afraid that's unavoidable.
Lastly, perhaps you should be using segmented memoryIsn't that what is what started my problem ? Putting DS into a different
segment than SS ?
Sorry, it should've been "should NOT be using segmented memory".
Then embrace it. Write all of the plumbing by hand. :)
And therefore it doesn't also make much sense for a "starter" to start
with 16 bit coding instead of the much easier 32 bit coding.
Because normally a program is not only executed once.
Even if done as a hobby, the result should be something useful.
Why mess around to make pictures with a camera.
but many programs written for MSDOS can still be executed in the current
32 bit Windows version.
The problem is, that AMD removed v86 mode in 64 bit mode
Microsoft didn't add a software DOS emulator in 64 bit Windows.
A program is written in order to be executed. To write a program
which can be executed on nearly none of the current computers
(without first installing additional software like DOSBox) doesn't
make much sense. And therefore it doesn't also make much sense for a "starter" to start with 16 bit coding instead of the much easier
32 bit coding.
A program is written in order to be executed. To write a program
which can be executed on nearly none of the current computers
(without first installing additional software like DOSBox) doesn't
make much sense. And therefore it doesn't also make much sense for a
"starter" to start with 16 bit coding instead of the much easier
32 bit coding.
1) In relation to "without first installing additional software ". Most programming languages need you to install software and configure it. Heaps of it. To create 16-bit programs al you need are three executables (an editor, the assembler and the linker) and *perhaps* (something like) DOSBox.
2) Its "much easier 32 bit coding" was, IIRC related to having all segments ontop of each other. Funny thing that, as that is exactly what the "tiny" memory model does for a 16-bit program. Yes, because it makes things
simple (my question was just about me thinking "outside the box").
As for using 32-bit (or 64-bit) coding instead of 16-bit ? I don't think
it matters much - though I think that the best way to learn actual programming is /not/ to have too much support from libraries and the like.
When you have it becomes too easy to create monstrocities instead of the way more apropriate (smaller, faster) processor commands. One example I still remember is how someone using a higher language isolated a bit in a value : (SomeValue & 2^SomeBit) <> 0. Yuck.
Bottom line : When learning to really program* I think that using a "dumb" target is best. 16-bit DOS programming would be a good choice, both because it offers only basic I/O support as well as most people nowerdays have computers and thus can do it anywhere (school as well as at home).
*as opposed to slap-dashing some scripting / high-level language together.
In other words : Its not about which language or platform you use, as long
as it teaches you what makes the bottom layer (the processor and I/O) tick, as well as makes you aware that everything comes with a cost (execution time and/or resource wise). Those are lessons that should be learned early on.
On 08.12.2021 10:16, R.Wieser wrote:
A program is written in order to be executed. To write a program
Why is 16-bit DOS programming a good choice in the year 2021?
The code below reads from stdin, converts any upper case to lower
case letters and writes it to stdout:
loop: bsr.l getc ; get char from stdin
cmpq.l #-1,r0 ; EOF
bne.b _10 ; branch if not
andq.l #0,r0
bsr.l exit
_10: cmp.b #'A',r0
blo.b _20
cmp.b #'Z',r0
bhi.b _20
add.b #'a'-'A',r0
_20: bsr.l putc ; write char to stdout
br.b loop ; go on
Is this 16 bit DOS or 32 bit Windows programming or is it even
a LINUX program?
Now the answer to the above question, it is neither a DOS, Windows or Linux code,
it is all three at the same time. Just set OS to 0,1 or 2 and the assembler will generate an executable for the selected OS from the same source code. Not even a single byte is generated by the assembler or a linker which is
not explicitly specified in the source code.
It doesn't matter how much software you have to install to create a
program.
But once created, it should be possible to execute the program on a
standard Windows installation without first installing additional
software.
It is always frustrating if you copy a program on an USB drive
to use it on a different PC and then all what you get is: This program
can't be executed because ......
No, that's not the reason. I always used .com programs in DOS so I never
had to mess around with segment registers.
To use 32 bit addressing modes has nothing to do with libraries.
This tells the compiler what he has to do, not how it has to be down.
Why is 16-bit DOS programming a good choice in the year 2021?
Is this 16 bit DOS or 32 bit Windows programming or is it even
a LINUX program?
*as opposed to slap-dashing some scripting / high-level language
together.
I would even go a step further and directly generate all bytes in
the executable file, this way you can see how the interface to the OS
works.
If it doesn't matter which platform you use, then there is no advantage
in using an obsolete platform instead of a current platform.
But it is a big disadvantage if the generated code can't be executed on a current platform.
Now the answer to the above question, it is neither a DOS, Windows or
Linux code,
it is all three at the same time.
Just set OS to 0,1 or 2 and the assembler will generate an executable for
the selected OS from the same source code.
I suspect you also need am assembler/compiler that isn't available (without installing) on any of the OS's.
So why dis anyone doing their own thing?
(16bit x86 asm DOS for me, if you noticed my attempt at a tetris update)
On 08.12.2021 18:37, Kerr-Mudd, John wrote:
I suspect you also need am assembler/compiler that isn't available (without installing) on any of the OS's.
As I already said, it doesn't matter what you have to install
to create a program. But the created program should run without
the need of additional software/libraries which are not part of
a standard OS installation. The assembler I use is a single exe
file and doesn't need to be "installed". And the C source of the
assembler (also only a single C file) can be compiled with any
C compiler.
So why dis anyone doing their own thing?
Because I learned more about assembly programming writing the
assembler than writing assembly programs using the assembler.
(16bit x86 asm DOS for me, if you noticed my attempt at a tetris update)
I know, but I can't test the programs because they don't run in
64 bit Windows. Why not do it with 1024 byte 32 bit exe files instead
of 256 byte 16 bit com files?
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 415 |
Nodes: | 16 (2 / 14) |
Uptime: | 106:08:49 |
Calls: | 8,692 |
Calls today: | 1 |
Files: | 13,250 |
Messages: | 5,948,274 |