6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 3:33 am

All times are UTC




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Thu May 25, 2017 11:27 pm 
Offline

Joined: Fri Nov 26, 2010 6:03 pm
Posts: 46
Location: NSW, Australia
I was recently reminded of an mid-1990s comp.lang.asm thread about programming in x86 assembler... using just the ASCII characters-- that is, the opcodes and oprands being limited to 0x20-0x7E --and the newsgroup went as far as producing a xmodem bootloader (..and quite possibly inspired a lot of exploit shellcode over the following decade..). The idea is certainly older than the 1990s, as ZX81 programers had their machine-code-in-REM statements trick. I checked and I couldn't really find anything for the 6502, which left me sleepless, so I started researching it myself.

With the vanilla 6502 CPU, $20-$7E doesn't give you much-- however most importantly the JSR, JMP, and RTS instructions is in there, and SEC BMI PHA PLA AND BIT ROL EOR LSR ADC ROR are what you have to work with. (SEI CLI PLP BVC BVS RTI as well, but they're next to useless here.)

The only memory-modifying (outside of the stack) instructions in the set are the bit-rolling ops ROL, ROR, and LSR-- so if you want to write to memory... guess what you've got to do!
Code:
.macro STA_ZP xx
            rol a
            rol xx
            rol a
            rol xx
            rol a
            rol xx
            rol a
            rol xx
            rol a
            rol xx
            rol a
            rol xx
            rol a
            rol xx
            rol a
            rol xx
.endmacro
All the register-immediate instructions are up around $Ax, so a LDA_XXXX macro is needed, or a bit more efficiently:
Code:
.macro LDA_IMZ
            and #64
            and #32
.endmacro

.macro LDA_IM xx                ;32<=x<=126
            LDA_IMZ
            eor #xx
.endmacro

.macro LDA_IMHE xx              ;even values 64<=x<=254
            LDA_IMZ
            eor #(xx >> 1)
            sec
            adc #((xx >> 1)-1)
.endmacro
Executable code-- at least anywhere you need to read, write, branch or jump to, has to be in areas of memory with the $20-$7E limit as well ($2020-$207E, $2120-$217E, ... $7E20-$7E7E). Code can reside beyond those areas, however it won't be possible to refer to it (LD/ST/JSR/JMP).

The only practical branch instruction BMI can only skip forward $20-$7E bytes.

What does an actual working 'printable 6502 machine code program' look like you ask? :) .. Here's a sample!
Code:
A`A`A`A`)@) IU8iT*.  *.  *.  *.  *.  *.  *.  *.  )@) IE8iD*." *." *." *." *." *." *." *." )@) It8is*.$ *.$ *.$ *.$ *.$ *.$ *.$ *.$ )@) I(JJ*.& *.& *.& *.& *.& *.& *.& *.& )@)    L !
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
> "*> "*> "*> "*> "*> "*> "*> "* &  & )< &  & *&"*&"*&"*&"*&"*&"*&"*&" $ > "*> "*> "*> "*> "*> "*> "*> "* &  & )<JJE"H " j)   h*> "*> "*> "*> "*> "*> "*> "*> " " 8*i   0TL !
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
jm2n22o00820m2oonn2122m0o360495420574o524k53210m00

(Edit: oops, the case on the letters is swapped, and the code isn't relocatable, but you get the idea..)
...this is Shellcode for the Commodore 64! :D ... The assembler source: http://kildall.apana.org.au/~cjb/C64/decode-ascii.asm

Progress photos from this little experiment are on my Twitter account : https://twitter.com/Chris_J_Baird/status/867611129073160192 ... https://twitter.com/Chris_J_Baird/status/867170413444333568


Top
 Profile  
Reply with quote  
PostPosted: Thu May 25, 2017 11:43 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
https://web.archive.org/web/20170714132 ... m/slammer/

Mike B.

[edit: updated dead link. Thanks, Ed]


Last edited by barrym95838 on Wed Jan 18, 2023 6:02 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri May 26, 2017 6:05 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
An interesting technical challenge, Chris!

I think, Mike, that Slammer! is an interesting idea too, but different, because while it supports printable-only machine code, the tool itself, which in effect unpacks that machine code and causes it to be executed, is not written in a printable-only dialect. (Edit: I'm wrong - see below)


Last edited by BigEd on Sat May 27, 2017 6:46 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri May 26, 2017 6:57 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Wow, thanks for posting. This is supremely absurd -- I love it!! 8) :mrgreen:

cjb wrote:
the opcodes and oprands being limited to 0x20-0x7E
As loaded, yes. But is there any prohibition on self-modifying code? (It won't be the only example where SMC can make a dramatic difference.)

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Fri May 26, 2017 7:31 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
Dr Jefyll wrote:
cjb wrote:
the opcodes and oprands being limited to 0x20-0x7E
As loaded, yes. But is there any prohibition on self-modifying code? (It won't be the only example where SMC can make a dramatic difference.)

Yep! A little shifting, masking, inverting, etc., on the memory-resident code and suddenly most of the instruction set might become available. Of course, figuring out what to shift, mask, invert, etc., to produce the desired results would be the real challenge. :D

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sat May 27, 2017 1:47 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
BigEd wrote:
I think, Mike, that Slammer! is an interesting idea too, but different, because while it supports printable-only machine code, the tool itself, which in effect unpacks that machine code and causes it to be executed, is not written in a printable-only dialect.

Are you sure about that, Ed?

https://web.archive.org/web/20170818125 ... LAMMER.TXT

Mike B.

[edit: updated dead link ... thanks, Ed]


Last edited by barrym95838 on Wed Jan 18, 2023 5:56 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat May 27, 2017 6:45 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Interesting! Slammer has been slammed. In hindsight, that's obviously possible. Thanks for the correction.


Top
 Profile  
Reply with quote  
PostPosted: Sat May 27, 2017 10:57 am 
Offline

Joined: Fri Nov 26, 2010 6:03 pm
Posts: 46
Location: NSW, Australia
BigDumbDinosaur wrote:
....the real challenge. :D
Well, you really don't need more than a base-16 decoder, a bit like I've already done :)

But yes-- a year ago I was playing around with One Instruction Set Computers, and there the challenge was even more extreme, having to find efficient ways to produce even the simplest instructions.

An idea I considered (but dismissed attempting in the concept code for being too memory-hungry and needing a lot of initialization) would be to take a cue from indirectly-threaded FORTH, and make most of the whole instruction set JSR'able.

(I've updated the code on the link in the OP, too-- I'd missed a non-ascii "adc #1" instruction.)


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 27, 2017 6:04 am 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
I recall the cable cross link between PC use ascii to
boot strap on another machine ( I forget what it was called ).
You used the serial cable to down load the ascii and then
changed the name to *.com and executed it. It would then
read the rest of the files across the cable.
Once there, you could then use the parallel cable that
was fast. It was something link or link something.
Oh well, a little more brain fade.
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 27, 2017 6:11 am 
Offline

Joined: Thu Mar 03, 2011 5:56 pm
Posts: 284
dwight wrote:
I recall the cable cross link between PC use ascii to
boot strap on another machine ( I forget what it was called ).
You used the serial cable to down load the ascii and then
changed the name to *.com and executed it. It would then
read the rest of the files across the cable.
Once there, you could then use the parallel cable that
was fast. It was something link or link something.
Oh well, a little more brain fade.
Dwight


"LapLink", perhaps? https://en.wikipedia.org/wiki/LapLink_cable


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 27, 2017 6:39 am 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
Yep, that was it. Thanks
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 27, 2017 4:26 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
rwiker wrote:

The Wikipedia article incorrectly shows pins 18 of each plug being wired together. Those two are "no connects."

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 27, 2017 5:03 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
BigDumbDinosaur wrote:
rwiker wrote:

The Wikipedia article incorrectly shows pins 18 of each plug being wired together. Those two are "no connects."

https://en.wikipedia.org/wiki/LPT#Pinouts

ETA: it's possible that some printer cables don't bother to connect all the grounds, and treat pin 18 as a No-Connect. Nevertheless, BDD, the spec says pin 18 is Ground. Your criticism of the Laplink connection chart is plainly, um, groundless!


Attachments:
350px-Parallel_port_pinouts.svg.png
350px-Parallel_port_pinouts.svg.png [ 20.93 KiB | Viewed 2153 times ]

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 28, 2017 6:40 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
Dr Jefyll wrote:
BigDumbDinosaur wrote:
rwiker wrote:

The Wikipedia article incorrectly shows pins 18 of each plug being wired together. Those two are "no connects."

https://en.wikipedia.org/wiki/LPT#Pinouts

ETA: it's possible that some printer cables don't bother to connect all the grounds, and treat pin 18 as a No-Connect. Nevertheless, BDD, the spec says pin 18 is Ground. Your criticism of the Laplink connection chart is plainly, um, groundless!

Oops! :oops: I was thinking of pin 18 on the 36 pin Centronics connector that is on a printer. Most printers apply 5 volts to pin 18.

Time for me to retire from this electronic stuff when I can't keep stuff I've worked with for some 40 years straight in my head anymore. :cry:

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 21 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: