Executing ASCII - an observation.

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Huh.  In the AVR instruction set, all of the branching, memory access, and IO instructions have the high bit (0x80) set.

This means, if you inadvertently were to, say, put a bunch of ASCII strings at location 0 of the flash instead of the code that should be there, that the CPU will happily execute that ASCII as relatively harmless instructions that don't trash anything other than the registers, eventually passing through it all and (hopefully) arriving at the actual code.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sounds like the basis for something like an

Esoteric Programming Language.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

...This means, if you inadvertently were to, say, put a bunch of ASCII strings at location 0 of the flash instead of the code that should be there, that the CPU will happily execute that ASCII as relatively harmless instructions that don't trash anything other than the registers, eventually passing through it all and (hopefully) arriving at the actual code.

 

avr-mike wrote:

Sounds like the basis for something like an Esoteric Programming Language.

 

Now there's a challenge.

 

Write a functional AVR program using only ASCII characters, ie 0x00 to 0x7F.

 

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why ?

 

You just to save one rjmp, and interrupt vectors will be a mess. 

 

 

add:

And if you want to save a instruction, just start your "real" code in addr 0, remember the AVR don't have a reset vector (or interrupt vectors), it just run code from a given addr. 

Last Edited: Thu. Feb 7, 2019 - 09:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:

Why ?

 

Why do people climb mountains?

 

 

(I don't think for a minute that it was in any way a serious suggestion but merely an interesting observation.)

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's a good challenge. There are still memory access instructions in range, so I/O access might still be possible. Ooops, no there aren't.

So there is really no way to do anything?

Also, no push/pop/ret.

 

ISRs can be used for branching, and one conditional execute is available (cpse).

 

And, the second byte must also be ASCII.

 

edit: This brings me a question - if we overflow the stack and run out of RAM, will it write to I/O, then registers? Not that we can do it here, since there is no way to configure ISRs to start filling up the stack.

Last Edited: Thu. Feb 7, 2019 - 10:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I noticed this property as well, a little over a year ago.  I looked into it for other purposes, but I hadn't considered a programming challenge.  Me like ;-)

 

Considering ASCII characters ' ' through '~', the opcodes represented are:

and
andi
cpi
eor
mov
or
ori
sbci
subi

The destination registers represented are:

r2
r3
r4
r5
r6
r7
r18
r19
r20
r21
r22
r23

All 32 source registers are represented, as are all 256 8-bit immediate operand values.

 

Constraining to alphanumeric (uppercase, lowercase, digits), the opcodes represented drop to:

andi
cpi
ori
sbci
subi

The destination registers represented are:

r18
r19
r20
r21
r22
r23

None of the opcodes employ source registers, but all 256 8-bit immediate operands values are represented.

 

So in either case, there are no instructions which affect anything except GP registers and SREG (not 'I', nor 'T').

 

If we expand to allow the use of ASCII control characters from 0 to 31, we add:

adc
add
cp
cpc
cpse
fmul
movw
muls
mulsu
nop
sbc
sub

... plus 127 invalid opcodes.  Still no way to affect anything except GP registers and SREG.  So a challenge would be limited to manipulating 12 of the GP registers, , and examining them with a debugger, simulator, or wrapper code.

 

El Tangas wrote:
if we overflow the stack and run out of RAM, will it write to I/O, then registers?
Yes.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Thu. Feb 7, 2019 - 04:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the keys to get something useful done are cpse and code wraparound due to PC overflow.

We can have different "subroutines" selected by cpse by using a register as routine selector. We only have ALU ops, so it needs to be a math challenge, I suppose? But no RAM...

 

edit: though "cpsne" would be far more useful here...

Last Edited: Thu. Feb 7, 2019 - 05:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

you can make a cpsne with cpse followed by a cpse rn,rn where rn is one of the 32 registers.

 

For a good solution : both the program AND the ASCII text should make sense :) 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What if you throw in, for example, the Latin-1

extended ASCII codes (accented vowels, etc.)

which have the 0x80 bit set?

--Mike