• How to access stack-based data (strings) when SS <> DS ?

    From R.Wieser@21:1/5 to All on Sat Dec 4 08:56:24 2021
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to R.Wieser on Sat Dec 4 12:47:41 2021
    On Sat, 4 Dec 2021 08:56:24 +0100
    "R.Wieser" <address@not.available> wrote:

    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?


    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sat Dec 4 15:57:16 2021
    John,

    No, sorry. Why would I put strings in the stack space?

    Lol ! Go troll someone else, will you.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to R.Wieser on Sat Dec 4 16:13:38 2021
    On Sat, 4 Dec 2021 15:57:16 +0100
    "R.Wieser" <address@not.available> wrote:

    John,

    No, sorry. Why would I put strings in the stack space?

    Lol ! Go troll someone else, will you.

    I'm sorry, it wasn't meant as a troll. I see now that I misread it.
    [context reinserted]
    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.

    If ss<>ds then to load /dx/ with a saved string pointer (which I think
    is what you want) I'd use the 'pop' instruction.

    I'd keep the strings in /ds/.

    I presume you're after something like /mov dx,[ss:stack+offset]/

    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sat Dec 4 18:41:26 2021
    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.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sat Dec 4 19:00:03 2021
    .... aaanndd I think I might be to blame for some of the confusion :

    When I said "lea dx,[Stack-based item]" I ment a local buffer in a
    procedure. So, it translates to "lea dx,[bp-xxxx]". The usage of "bp" ofcourse causes the target to be in the SS segment.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to R.Wieser on Sat Dec 4 20:28:14 2021
    On Sat, 4 Dec 2021 18:41:26 +0100
    "R.Wieser" <address@not.available> wrote:

    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 ?

    You are very kind; no I think befuddlement is setting in here. OTOH I
    rarely use /lea/.

    I presume you're after something like /mov dx,[ss:stack+offset]/

    Definitily not.


    OK I'll bow out, I'm clearly not understanding your requirement.

    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Sun Dec 5 14:27:59 2021
    On Sat, 4 Dec 2021 08:56:24 +0100, R.Wieser wrote:
    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

    Well, you'll have to change the segment register to the correct segment when using interrupts which only accept offset(s).

    As for general use... Is segment override not applicable? e.g.

    mov ax, ss:[bx]
    mov dx, ds:[sp]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Dec 5 08:56:51 2021
    John,

    OTOH I rarely use /lea/.

    In a nutshell : "lea" returns a pointer to somewhere. "mov" copies to/from somewhere.

    Although "lea ax,address" and "mov ax,offset address" return the same thing, "lea"s strength lies in that it can accept a relative part in the form of a register.

    Like "lea ax, [si+4]". Load ax with the address four bytes beyond what SI
    is pointing at.

    OK I'll bow out, I'm clearly not understanding your requirement.

    I posted a small addendum. My mistake was that I assumed that "[stack
    based]" would be understood as referring to a procedure-local variable or buffer. IOW, "[stack based]" translates, for my example, to "[bp-xxxx]"

    To be honest, I have not ever heard someone storing / retrieving data using absolute adressing inside the SS segment. Instead always relative to either
    BP or SP.

    Code example :
    - - - - - - - - - - - - - - - - - -

    MyProc:
    push bp
    mov bp,sp
    sub sp,0100h ;<- create a local buffer.

    ...

    lea dx,[bp-0100h] ;<- Point to the buffer
    mov ah,09h
    int 21h

    - - - - - - - - - - - - - - - - - -

    Now imagine that you're using a memory model where DS <> SS. The problem
    than is that in the above code DX is relative to SS, but int 21, ah=09h
    expects it to be relative to DS.

    What I was wondering is how this would be handled by/in professional
    software (compilers).


    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 ...

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to R.Wieser on Sun Dec 5 10:32:58 2021
    On Sun, 5 Dec 2021 08:56:51 +0100
    "R.Wieser" <address@not.available> wrote:

    [Full explanation snipped for brevity]


    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 ...


    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.


    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Dec 5 12:43:33 2021
    JJ,

    As for general use... Is segment override not applicable? e.g.

    For "general use" as in what I write myself ? Ofcourse.

    The problem is that most system calls (like for example int 21h, AH=09h - display a string) are hard-tied to using the DS segment when they access the data that is pointed to. No override possible.

    But, it looks I painted myself in a corner here.

    Although you certainly /can/ create a program where DS and SS are set to different segments, none of the memory models (tiny, small, etc.) you can
    chose do that.

    Probably for a good reason. The reason I bumped into. Its simply /way/ to cumbersome to have to deal with a SS <> DS setup. :-)

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Dec 5 13:11:44 2021
    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
    ?

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to R.Wieser on Sun Dec 5 12:21:57 2021
    On Sun, 5 Dec 2021 13:11:44 +0100
    "R.Wieser" <address@not.available> wrote:

    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 ?

    Yes. I'm not the whizz programmer you thought I was!

    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Dec 5 14:59:00 2021
    John,

    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!

    I think you are /at least/ knowledgable, but with a different interrest in programming than I have.

    I've been programming Assembly for ... ages now, and have actually written
    code as I posted in the grandparent post (three-and-half hours ago).

    That was before I found out that Borlands Tasm allowed some syntactic sugar
    to make usage of procedures and local variables (and stack-based, pushed arguments!) /much/ easier.

    And as you might have noticed, I still do not know everything about it
    (might already have forgotten a thing or two too). And I hope it stays that
    way - otherwise I have to find myself another hobby... :-)

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alexei A. Frounze@21:1/5 to R.Wieser on Sun Dec 5 22:25:10 2021
    On Saturday, December 4, 2021 at 12:18:18 AM UTC-8, R.Wieser wrote:
    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.

    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.
    Another option is, if your assembler can examine variable/label
    names, you may encode the segment into the name, which is ugly,
    but may work.
    Lastly, perhaps you should be using segmented memory
    or you could generate code by some means other than the assembler
    and more higher level.

    Alex

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mateusz Viste@21:1/5 to Alexei A. Frounze on Mon Dec 6 09:30:32 2021
    2021-12-05 at 22:25 -0800, Alexei A. Frounze wrote:
    Lastly, perhaps you should be using segmented memory or you could
    generate code by some means other than the assembler and more higher
    level.

    That's an excellent advice. There's a very good instructional video
    about exactly that on youtube: https://youtu.be/1S1fISh-pag

    Mateusz

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Dec 6 14:33:29 2021
    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 variable
    is allocated

    Nope. That "lea dx,[bp-xxxx]" implicitily uses SS as its base. There is no
    way to tell by looking at DX itself.

    (assuming it can actually allocate a variable on the stack just like in
    the data segment)

    <huh?> You're the second one who doubts that, even though procedure-local variables are a thing in most any language ...

    and if the assembler can conditionally assemble code based on that,
    then you can eliminate some unnecessary segment manipulation.

    I'm not at all sure I can override build-in menemonics to execute a macro
    ... Otherwise I would need to add pseudo(?) code around pretty-much everything.

    Lastly, perhaps you should be using segmented memory

    Isn'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
    assembler and more higher level.

    :-) I like Assembly because it /doesn't/ hide all kinds of stuff from me.

    Thanks for the suggestions.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Herbert Kleebauer@21:1/5 to R.Wieser on Mon Dec 6 19:01:39 2021
    On 06.12.2021 14:33, R.Wieser wrote:

    :-) 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. That's like writing a novel in ancient Greek. 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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Dec 6 21:16:50 2021
    Herbert,

    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 ...

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Herbert Kleebauer@21:1/5 to R.Wieser on Tue Dec 7 00:19:16 2021
    On 06.12.2021 21:16, R.Wieser wrote:

    But nearly no PC can execute 16 bit code directly these days.

    For starters, why including a restriction like "directly" ? How does that matter ?

    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.


    And for seconds, how does "nearly no PC" matter as long as mine does ?

    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.


    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.

    Even if done as a hobby, the result should be something useful. And
    a program is only useful if it can be executed. Maybe somebody else
    would like to use the functions provided by the code, but it is
    useless because he can't execute it on current hardware. I don't
    see any advantage in writing code for obsolete systems, but many
    disadvantages.


    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.

    Why mess around to make pictures with a camera. I'm sure there are lots of well-payed professional photographer which can deliver much better quality in
    a much shorter time. But if you take pictures, store them in a format which
    can be displayed on current systems without the need of installing additional software. And if you write software, use a format which can be executed
    on current systems.


    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 ...

    The operating system MSDOS may be obsolete since 20 years, 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 and
    Microsoft didn't add a software DOS emulator in 64 bit Windows. In Windows 11 you now can install and execute Android apps but no 16 bit DOS code. Well
    done Microsoft! https://docs.microsoft.com/en-us/windows/android/wsa/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alexei A. Frounze@21:1/5 to R.Wieser on Mon Dec 6 22:40:07 2021
    On Monday, December 6, 2021 at 5:33:38 AM UTC-8, R.Wieser wrote:
    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 variable
    is allocated
    Nope. That "lea dx,[bp-xxxx]" implicitily uses SS as its base. There is no way to tell by looking at DX itself.

    I'm not suggesting to magically deduce something from a register.
    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).

    (assuming it can actually allocate a variable on the stack just like in
    the data segment)
    <huh?> You're the second one who doubts that, even though procedure-local variables are a thing in most any language ...

    I don't remember the details and they are important.

    and if the assembler can conditionally assemble code based on that,
    then you can eliminate some unnecessary segment manipulation.
    I'm not at all sure I can override build-in menemonics to execute a macro
    ... Otherwise I would need to add pseudo(?) code around pretty-much everything.

    I'm afraid that's unavoidable.

    Lastly, perhaps you should be using segmented memory
    Isn'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".

    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.

    Then embrace it. Write all of the plumbing by hand. :)

    Alex

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mateusz Viste@21:1/5 to Herbert Kleebauer on Tue Dec 7 09:31:13 2021
    2021-12-07 at 00:19 +0100, Herbert Kleebauer wrote:
    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.

    In this line of thoughts, writing Java doesn't make sense, because it
    requires installing a JRE first. Writing JavaScript doesn't make sense
    because it requires a browser, even PHP is stupid because it is not
    stand-alone executable code...

    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.

    16-bit code has bigger chances of being useful in a few years than a
    "modern" code has, given that libraries change, operating systems
    change, etc. DOS is one of the very few "APIs" that are stable, while
    the rest of the IT ecosystem is a moving target. Nowadays it is easy to
    run a 16-bit program in a browser. Try doing the same with any other
    executable program.

    Even if done as a hobby, the result should be something useful.

    Ah, I only noticed the name now... A German. Should've guessed earlier.

    Mateusz

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Tue Dec 7 10:17:02 2021
    Alexei,

    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).

    To be honest, I didn't think of that.

    It would possibly be workable for simple situations, like the
    single-argument int 21h, AH=09h. It wouldn't for anything that used more
    than one pointer argument (into different segments) though.

    IOW, it would need constant scrutiny by me, the programmer, to make sure
    that all (applied by macros ?) "fixes" would actually work. :-( Ehh...
    no. Although possible not really a solution.

    I don't remember the details and they are important.

    I did not provide any other than "[stack based item]", which I thought would
    be picked up by anyone here as either "[bp-xxxx]" or "[sp+xxxx]". I was mistaken. :-|

    I'm afraid that's unavoidable.

    That is what I thought, but wanted to make sure I did not overlook anything
    / something simpler.

    Lastly, perhaps you should be using segmented memory
    Isn'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".

    :-) In that case, I'm not (yet). I've been using the "tiny" memory model where CS = DS = SS , as that one is easiest to work with and I simply have never had the need for more memory (in relation to those three segments).

    Its just that I saw a possible situation (I was thinking about recursion and how it gobbles stack memory), and wondered how that would work. As it turns out, not even Borland actually wished to burn their fingers on it - all its memory models set SS to the same as DS.

    Then embrace it. Write all of the plumbing by hand. :)

    As programmers we're supposed to be "lazy". If something repeats than we rather spend an hour to solve a 10 minute problem than to write it twice,
    let alone more than that. :-)

    The bottom line is that a memory model with SS <> DS is simply no fun to
    deal with. As I could have guessed if I would have looked at the offered memory models earlier. Hmmm... Probably would not have stopped me from
    asking though. <whistle>

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Tue Dec 7 09:37:08 2021
    Herbert,

    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.

    Fail. No such destinction was made by you. And you are talking to someone
    who (obviously?) has been doing 16-bit programming for a while now. IOW, it looks like you are shifting goalposts.

    Because normally a program is not only executed once.

    Fail again, as you making an assumption towards what *I* do with the result.
    I could ofcourse tell you I've written 16-bit programs years ago that I
    still use, but somehow I think you will just discard that as an "exception
    to the rule".

    Even if done as a hobby, the result should be something useful.

    And thats the actual point, isn't it ? You do not see the usefullness of
    what I'm doing.

    But instead of asking you just come out challenging me, suggesting that I should stop doing it, even though I enjoy doing it.

    And for the record, enjoying doing something is all thats needed for a
    hobby - even if the result is of no use to anyone, including the one
    practicing it. I'm sure you can think of a few hobbies like that.. I'll give you the first one : collecting sugar sachets..

    Why mess around to make pictures with a camera.

    You hit the nail on the head, but do not seem to be aware of it ....

    Why /would/ you take pictures ? You would just waste *heaps* of time
    making them, on possibly /very/ expensive equipment. And than spend even
    more time on tagging them, possibly color-correcting, cropping and than sorting/putting them into easy-findable-and-viewable groups. All so they can be shown off to people who, more often than not, do not really care.

    And by the way, I've got a friend which does all of the above, and is
    mulling to go professional. He's simply that good. Something he would not have known if he hadn't picked up photographing as a hobby ...

    but many programs written for MSDOS can still be executed in the current
    32 bit Windows version.

    Funny, the thing you started with was claiming that they wouldn't - and that
    I, for that reason, should not be doing any 16-bit programming (anymore) ...

    The problem is, that AMD removed v86 mode in 64 bit mode

    So they should have to support a 16 /as well as/ a 32 bit mode next to the native, 64-bit one ? 'Cause that is what they did : just like a 32-bit processor supported a 16-bit mode (one step down), a 64-bit processor now supports a 32-bit mode.

    Microsoft didn't add a software DOS emulator in 64 bit Windows.

    Than look around a bit. Don't expect MS to just drop everything into your
    lap. Google for "DOSBox 64-bit".

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Wed Dec 8 10:16:46 2021
    Herbert,

    A reply to your "no good for starters" claim :

    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.

    Though I think that programming machine code on a micro controller, possibly mounted on a model car or a robotic something, would be even better : most people need, especially when starting, to see a direct result of what they
    have put their energy into.

    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.

    I hope that answers your (second, new) question.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Herbert Kleebauer@21:1/5 to R.Wieser on Wed Dec 8 17:39:07 2021
    On 08.12.2021 10:16, R.Wieser wrote:

    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.

    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 ......


    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").

    No, that's not the reason. I always used .com programs in DOS so I
    never had to mess around with segment registers. But I also used
    32 bit registers and addressing modes in 16 bit DOS programs, because
    that makes assembly programming so much easier.


    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.

    To use 32 bit addressing modes has nothing to do with libraries.


    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.

    This tells the compiler what he has to do, not how it has to be down.
    Look at the generated code and you will see, that in most case the
    compiler generates better code than an average assembly programmer.


    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).

    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?


    *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.


    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.

    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.
    Not even a single byte is generated by the assembler or a linker which is
    not explicitly specified in the source code.



    OS=0 ; 0: DOS 1: WINDOWS 2: LINUX ;;

    ;=========================================================================== ;===========================================================================

    IF OS==0 ; DOS
    @=$100
    ENDIF

    ;=========================================================================== ;===========================================================================

    IF OS==1
    UseIdatSection=0 ; 0 if no idat section is used
    UseUdatSection=0 ; 0 if no udat section is used

    dc.w 'ZM',dosfilesize\512, (dosfilesize-1)/512+1
    dc.w 0,doshead_end/16,0,$ffff,0,dosstack,0,dosmain
    dc.w 0,reloc,0,0,0,0,0,0,0
    dc.l 0,0,0,0,0,WinHeader
    reloc:
    doshead_end:
    @=$0
    dosmain:move.w s6,-(sp)
    move.w (sp)+,s0
    move.w #_text,r1
    move.b #$09,m0
    trap #$21
    move.w #$4c01,r0
    trap #$21
    _text: dc.b 'Nice to meet somebody who is still using DOS,',13,10
    dc.b 'but his program requires Win32.',13,10,'$'
    even 16

    dosstack=@+256
    dosfilesize=@+256

    ImageBase== $00400000
    SectionAlignment== 4096
    FileAlignment== 512
    WinHeader=@@
    @=ImageBase
    dc.b 'PE',0,0
    dc.w $014c,NumberOfSections
    dc.l $36a57950,0,0
    dc.w SizeOfOptionalHeader,$010f

    @a=@
    dc.w $010b
    dc.b 5,12
    dc.l SizeOfCode,SizeOfInitializedData,SizeOfUninitializedData
    dc.l winmain-ImageBase,BaseOfCode,BaseOfData,ImageBase
    dc.l SectionAlignment,FileAlignment
    dc.w 4,0,0,0,4,0
    dc.l 0,SizeOfImage,SizeOfHeaders, 0
    dc.w 3 ; 2:GUI 3:character subsystem.
    dc.w 0
    dc.l $100000,$1000,$100000,$1000,$0,NumberOfRvaAndSize

    @b=@
    dc.l 0,0,imp_start,imp_size,0,0,0,0,0,0,0,0,0,0,0,0
    dc.l 0,0,0,0,0,0,0,0,iat_start,iat_size,0,0,0,0,0,0
    NumberOfRvaAndSize = (@-@b)/8
    SizeOfOptionalHeader = @-@a

    @a=@
    dc.b '.text',0,0,0
    dc.l VSizeOf_text,VBaseOf_text,FSizeOf_text,FBaseOf_text,0,0
    dc.w 0,0
    dc.l $e0000020

    IF UseIdatSection
    dc.b '.idat',0,0,0
    dc.l VSizeOf_idat,VBaseOf_idat,FSizeOf_idat,FBaseOf_idat,0,0
    dc.w 0,0
    dc.l $e0000040
    ENDIF

    IF UseUdatSection
    dc.b '.udat',0,0,0
    dc.l VSizeOf_udat,VBaseOf_udat,FSizeOf_udat,FBaseOf_udat,0,0
    dc.w 0,0
    dc.l $e0000080
    ENDIF

    NumberOfSections=(@-@a)/40
    evencom FileAlignment
    SizeOfHeaders==@@

    FBaseOf_text==@@
    VBaseOf_text==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment
    BaseOfCode==VBaseOf_text
    @=ImageBase+VBaseOf_text

    iat_start=@-ImageBase

    KERNEL32_thunk:
    ExitProcess:: dc.l KERNEL32_ExitProcess -ImageBase
    GetStdHandle:: dc.l KERNEL32_GetStdHandle -ImageBase
    ReadFile:: dc.l KERNEL32_ReadFile -ImageBase
    WriteFile:: dc.l KERNEL32_WriteFile -ImageBase
    dc.l 0

    iat_size=@-ImageBase-iat_start

    imp_start==@-ImageBase
    imp:

    dc.l KERNEL32_import -ImageBase
    dc.l 0
    dc.l 0
    dc.l KERNEL32_name -ImageBase
    dc.l KERNEL32_thunk -ImageBase

    dc.l 0,0,0,0,0

    imp_size==@-imp

    KERNEL32_name:
    dc.b 'KERNEL32.dll',0
    even

    KERNEL32_import:
    dc.l KERNEL32_ExitProcess -ImageBase
    dc.l KERNEL32_GetStdHandle -ImageBase
    dc.l KERNEL32_ReadFile -ImageBase
    dc.l KERNEL32_WriteFile -ImageBase
    dc.l 0
    even

    KERNEL32_ExitProcess:
    dc.w 0
    dc.b 'ExitProcess',0
    even
    KERNEL32_GetStdHandle:
    dc.w 0
    dc.b 'GetStdHandle',0
    even
    KERNEL32_ReadFile:
    dc.w 0
    dc.b 'ReadFile',0
    even
    KERNEL32_WriteFile:
    dc.w 0
    dc.b 'WriteFile',0
    even
    seg32
    winmain::

    ENDIF

    ;=========================================================================== ;===========================================================================

    IF OS==2 ; Linux
    seg32
    @=$08048000
    code_offset=@@
    code_addr:
    ;--------------------------- ELF header -----------------------------------
    dc.l $464c457f,$00010101,0,0,$00030002,1,main,$34,0,0,$00200034,2,0
    dc.l 1,code_offset,code_addr,code_addr,code_filez,code_memsz,5,4096
    dc.l 1,data_offset,data_addr,data_addr,data_filez,data_memsz,6,4096 ;--------------------------- code ------------------------------------------
    main:
    ENDIF

    ;=========================================================================== ;===========================================================================

    ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

    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


    ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM



    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; OS specific functions: getc, putc, exit ;;
    ;; 0: DOS 1: WINDOwS 2: LINUX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


    ;=========================================================================== ;===========================================================================

    IF OS==0 ; DOS

    getc: eor.l r0,r0
    movem.l r0-r7,-(sp)
    move.w #$3f00,r0
    lea.w 28.b(r7),r1
    move.w #1,r2
    eor.w r3,r3
    trap #$21
    bcs.b _20
    cmp.w r0,r2
    movem.l (sp)+,r0-r7
    beq.b _10
    move.l #-1,r0
    _10: rts.l
    _20: move.b #-1,r0
    br.b exit

    putc: movem.l r0-r7,-(sp)
    move.w #$4000,r0
    lea.w 28.b(r7),r1
    move.w #1,r2
    move.w r2,r3
    trap #$21
    bcs.b _20
    cmp.w r0,r2
    bne.b _20
    movem.l (sp)+,r0-r7
    rts.l
    _20: move.b #-1,r0
    br.b exit

    exit: move.b #$4c,m0
    trap #$21

    ENDIF

    ;=========================================================================== ;===========================================================================

    IF OS==1 ; WINDOWS

    getc: eor.l r0,r0
    movem.l r0-r7,-(sp)
    lea.l 28.b(r7),r1
    move.l r0,-(sp)
    move.l r7,r2

    add.l _handle,r0
    bne.b _10
    moveq.l #-10,-(sp)
    jsr.l (GetStdHandle)
    move.l r0,_handle

    _10: moveq.l #0,-(sp)
    move.l r2,-(sp)
    moveq.l #1,-(sp)
    move.l r1,-(sp)
    move.l r0,-(sp)
    jsr.l (ReadFile)
    move.l (sp)+,r1
    or.l r0,r0
    bne.b _20
    orq.l #-1,r0
    br.b exit
    _20: cmp.l #1,r1
    movem.l (sp)+,r0-r7
    beq.b _30
    move.l #-1,r0
    _30: rts.l

    even4
    _handle:dc.l 0


    putc: movem.l r0-r7,-(sp)
    lea.l 28.b(r7),r1
    move.l r0,-(sp)
    move.l r7,r2

    eor.l r0,r0
    add.l _handle,r0
    bne.b _10
    moveq.l #-11,-(sp)
    jsr.l (GetStdHandle)
    move.l r0,_handle

    _10: moveq.l #0,-(sp)
    move.l r2,-(sp)
    moveq.l #1,-(sp)
    move.l r1,-(sp)
    move.l r0,-(sp)
    jsr.l (WriteFile)
    move.l (sp)+,r1
    or.l r0,r0
    bne.b _20
    _30: orq.l #-1,r0
    br.b exit
    _20: cmp.l #1,r1
    bne.b _30
    movem.l (sp)+,r0-r7
    rts.l

    even4
    _handle:dc.l 0


    exit: move.l r0,-(sp)
    jsr.l (ExitProcess) ; exit program

    ENDIF

    ;=========================================================================== ;===========================================================================

    IF OS==2 ; LINUX

    getc: eor.l r0,r0
    movem.l r0-r7,-(sp)
    move.l #0,r3 ; stdin
    lea.l 28.b(r7),r2
    move.l #1,r1 ; 1 byte
    move.l #3,r0 ; read
    trap #$80
    tst.l r0,r0
    bmi.b _10
    movem.l (sp)+,r0-r7
    bne.b _20
    orq.l #-1,r0
    _20: rts.l
    _10: orq.l #-1,r0 ; return code
    br.b exit


    putc: movem.l r0-r7,-(sp)
    move.l #1,r3 ; stdout
    lea.l 28.b(r7),r2
    move.l #1,r1 ; 1 byte
    move.l #4,r0 ; write
    trap #$80
    cmpq.l #1,r0
    bne.b _10
    movem.l (sp)+,r0-r7
    rts.l
    _10: orq.l #-1,r0 ; return code
    br.b exit


    exit: move.l r0,r3 ; return code
    move.l #1,r0 ; exit
    trap #$80

    ENDIF ;=========================================================================== ;===========================================================================


    ;=========================================================================== ;===========================================================================
    IF OS==1 ; WINDOWS
    VSizeOf_text==@-Imagebase-VBaseOf_text
    @a=@
    evencom FileAlignment
    @=@a

    FSizeOf_text==@@-FBaseOf_text
    SizeOfCode==FSizeOf_text

    FBaseOf_idat==@@
    VBaseOf_idat==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment
    BaseOfData==VBaseOf_idat
    @=ImageBase+VBaseOf_idat
    ENDIF

    ;===========================================================================

    IF OS==2 ; Linux
    code_filez=@@-code_offset
    code_memsz= @-code_addr
    even 4
    @=(@+4095)/4096*4096+(@@\4096)
    data_offset=@@
    data_addr:
    ENDIF

    ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

    ;--------------------------- initialized data ------------------------------ ;some_initialized_data: dc.l 3

    ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM


    ;===========================================================================
    IF OS==1 ; WINDOWS

    VSizeOf_idat==@-Imagebase-VBaseOf_idat
    @a=@
    evencom FileAlignment
    @=@a
    FSizeOf_idat==@@-FBaseOf_idat

    SizeOfInitializedData==FSizeOf_idat

    FBaseOf_udat==@@
    VBaseOf_udat==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment
    @=ImageBase+VBaseOf_udat
    ENDIF

    ;===========================================================================

    ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

    ;--------------------------- uninitialized data ---------------------------- ;some_uninitialized_data: blk.b 20 ;---------------------------------------------------------------------------

    ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

    ;===========================================================================
    IF OS==1 ; WINDOWS

    VSizeOf_udat==@-Imagebase-VBaseOf_udat
    @a=@
    evencom FileAlignment
    @=@a
    FSizeOf_udat==@@-FBaseOf_udat

    SizeOfUninitializedData==VSizeOf_udat
    SizeOfImage==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment
    ENDIF

    ;===========================================================================

    IF OS==2 ; Linux
    data_filez=@@-data_offset
    data_memsz= @-data_addr
    ENDIF

    ;===========================================================================

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to Herbert Kleebauer on Wed Dec 8 17:37:29 2021
    On Wed, 8 Dec 2021 17:39:07 +0100
    Herbert Kleebauer <klee@unibwm.de> wrote:

    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.

    []
    Wonderful stuff, but it's not a standard language. 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)



    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Wed Dec 8 22:19:34 2021
    Herbert,

    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 doesn't work that way for Windows programs ...

    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 ......

    ... and reading from the above you know it.

    But if that is your yardstick I guess thats the end of the story. Its
    over, curtains close, you all can go home now.


    It has to be said though : where I can run those 16-bit DOS programs on any Win32 'puter and with the help of DOSBox also on a Win64 machine, your own 64-bit programs won't have it that easy. Apart from those dependancies they will never run on a Win32 machine, and they might also barf on an earlier version of Windows.

    No, that's not the reason. I always used .com programs in DOS so I never
    had to mess around with segment registers.

    lol. You are disagreeing with while agreeing with me. The only difference
    is that you look at the COM model, while I thought of the EXE one.

    To use 32 bit addressing modes has nothing to do with libraries.

    In that case, might I maybe have ment something else ? And if so, what ?
    Maybe I was referring to something we already spoke of ? Do remember that
    I also said "(or 64-bit)". Does that perhaps ring a bell ?

    Playing dumb doesn't score you any points. It just shows what kind of
    person you want to be.

    This tells the compiler what he has to do, not how it has to be down.

    Its hard isn't it ? Understanding the point of an example ? I've also
    made no mention of a language, or if it would be compiled or not. Funny
    how you seem know exactly what I've must have ment when it benefits you, but have lots of trouble figuring it out when it doesn't ...

    Why is 16-bit DOS programming a good choice in the year 2021?

    Why are you ignoring that I also mentioned other possible platforms ?

    Is this 16 bit DOS or 32 bit Windows programming or is it even
    a LINUX program?

    Your point ?

    *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.

    It looks like what you said has something to do with what you quoted there,
    but heaven knows what.

    And no, you would not be able to do that. Or you would need to drop the
    "the OS" and be more specific than that.

    If it doesn't matter which platform you use, then there is no advantage
    in using an obsolete platform instead of a current platform.

    And you have been refusing to listen to what I've been telling you, only
    taking your own circumstances into account. On multiple points.

    But it is a big disadvantage if the generated code can't be executed on a current platform.

    And water is still wet ?

    Now the answer to the above question, it is neither a DOS, Windows or
    Linux code,
    it is all three at the same time.

    :-) Yeah, if you massage it enough I'm sure that you will be able to get something runnable outof it. Just have to either replace those "getc" and "putc" pseudos with code outof some library, wrap some target-environment specific initialisation and finalisation code around it and sure it will do something.

    You will have no clue what is actually executed though.

    Heck, maybe that compiler you mentioned earlier wil just replace it with something else altogether !

    Just set OS to 0,1 or 2 and the assembler will generate an executable for
    the selected OS from the same source code.

    "You keep using that word, Assembler. I don't think it means what you think
    it means."
    -- The princes bride.

    As for that listing below it ? Nope, its not. Its several programs -
    which do not even need to be doing the same* - pushed together and using the preprocessor to filter the selected parts out - and ofcourse some of the
    above mentioned massaging of its pseudos.

    *and if youre not /very/ carefull *will* do something different. Perhaps
    even on purpose ...

    But hey, if your thing is to "prove" that you can have some program that
    will work on multiple platforms than you failed. Before you can run it
    you first need to pull it thru that "Assembler" of yours, and than it looses all of its multi-platform capabilities.


    But lets draw the line here.

    You've shown that for you only your own circumstances matter (even ignoring that I mentioned other environments and languages), as well as rather
    quickly deviating from the subject to something else you think you can
    control.

    So, goodbye. Have a good life.

    Regards,
    Rudy Wieser

    P.s.
    I did not actually try to look at that lengthy code. Your description made clear that you tried to do the "assembly" equivalent of a "portable" C
    program. And thats old hat.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Herbert Kleebauer@21:1/5 to John on Wed Dec 8 22:31:50 2021
    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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to Herbert Kleebauer on Thu Dec 9 21:43:14 2021
    On Wed, 8 Dec 2021 22:31:50 +0100
    Herbert Kleebauer <klee@unibwm.de> wrote:

    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.

    That's worthy, but it isn't everyone's path.

    (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?

    Sorry.

    'cos I'm stuck in the past? I'm late to the demoscene!
    1k - ridiculous overhead!

    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)