Assembler equivalent

Can someone please give me the assembler language equivalent for while(!(PIND&4)); ?

Not until you tell use which processor.

:-[

Its Atmega 328P

abbanerjee: Can someone please give me the assembler language equivalent for

Why ? The compiler will produce assembler code as good or better than you can.

Perhaps you just want to know what the code does? PIND is the assembler instruction to read Port D &4 is pretty much the assembler instruction to AND the value with B0000 0100 which means that all bits other than bit 2 are ignored. ! (NOT) means that it loops as long as the value at bit2 is NOT 1

...R Edited to change Bit3 to Bit2 as pointed out in Reply #4 - apologies for the error

the value at bit3 is NOT 1

sp. “bit 2”

void setup() 
{
  while(!(PIND&4));
}

Compiles to…

00000090 <setup>:
  90:	4a 9b       	sbis	0x09, 2	; 9
  92:	fe cf       	rjmp	.-4      	; 0x90 <setup>
  94:	08 95       	ret

Thanks.

Now the question becomes how to get the assembly dump …

Now the question becomes how to get the assembly dump ...

Or, what do you do with this this information now.

robtillaart: Now the question becomes how to get the assembly dump ...

A bit of Python...

import fnmatch
import os
import subprocess
import string

pathok = False
pathlist = os.environ['PATH'].split( os.pathsep )
for path in pathlist:
  testme = os.path.join(path,'avr-objdump.exe')
  if os.path.exists(testme):
    pathok = True
    break

if not( pathok ):
  #arduinoroot = 'C:\\Arduino\\arduino-1.0.5\\'
  arduinoroot = 'C:\\Arduino\\arduino-1.6.5\\'
  pathlist.append( arduinoroot + 'hardware\\tools\\avr\\utils\\bin' )
  pathlist.append( arduinoroot + 'hardware\\tools\\avr\\bin' )
  pathlist.append( arduinoroot + 'hardware\\tools\\avr\\etc' )
  pathnew = os.pathsep.join( pathlist )
  os.environ['PATH'] = pathnew

os.chdir( arduinoroot )

tempdir = os.environ.get('TEMP')
tempfile = os.path.join(tempdir,'Junk.cpp')

matches = []
for root, dirnames, filenames in os.walk(tempdir):
  for filename in fnmatch.filter(filenames, '*.elf'):
    matches.append(os.path.join(root, filename))

matches.sort( key=os.path.getmtime )

if len(matches) > 0:
  f = open(tempfile, 'w')
  # fix? Also include -j .bss -j .data -j .text ?
  subprocess.call(['avr-objdump.exe','-S','-z',matches[len(matches)-1]],stdout=f)
  f.close()
  os.system( 'start ' + tempfile )

And some "DOS" batch to kick it off...

@Echo Off
C:\Python32\python C:\Path32\ds.py

The source code of the sketch is not intermixed but everything else is. There is a way to also intermix the sketch. I can't remember it now. Unfortunately I did not update the Python when I could remember. Oh, well. Something for version 2.

LarryD: Or, what do you do with this this information now.

I use that sort of thing to more quickly learn assembly. (Comparing generated assembly to C / C ++ source.)

However, given how specific @abbanerjee's question was I doubt that is the intent.

@Coding Badly: Thanks for your answer. I am new to the environment and I am trying to figure out if what I want to do can be done using atmega328p. I basically want to poll a pin that oscillates at 1 Mhz. This is connected to a FIFO producing 1 byte at every rising edge. I want to then encode the upper nibble into two bits to pack a byte every 4 times the pin goes high at the rate of 1 Mhz. Given that 328p does 16 Mhz, that leaves me 15 clock cycles to do everything I want to do after polling the pin. Hence I am considering moving from Arduino to assembler and before I take the plunge asses some of the feasibilities. I this case I am being a bit lazy instead of disassembling things myself I must admit.

I am not fully conversant with the toolchain so indeed I wanted to ask how to disassemble, but the python code is nice to have.

Collecting the data will probably (barely) work. You will have to collect with interrupts disabled.

Pursuing an assembly solution is the right choice. The compiler does a good job but, for very time critical code, there are usually a few cycles that can be squeezed out working in assembly.

I suggest you first code it in C. Ideally, get it working at a slower bitrate. Then dissassemble it and hunt for optimizations.

Finally, entry is going to be the most difficult part. You will very likely need a few dozen cycles to prepare the loop.

This... https://github.com/Coding-Badly/TinyISP/blob/master/KnockBangReceiver.cpp#L268-608 ...is similar to what you are trying to do.

abbanerjee: I basically want to poll a pin that oscillates at 1 Mhz. This is connected to a FIFO producing 1 byte at every rising edge. I want to then encode the upper nibble into two bits to pack a byte every 4 times the pin goes high at the rate of 1 Mhz. Given that 328p does 16 Mhz, that leaves me 15 clock cycles to do everything I want to do after polling the pin.

Sounds like a cross-post of http://forum.arduino.cc/index.php?topic=332573

I just want to point out that "polling a pin" does not happen in one cycle. You would need to read the pin (probably 2 cycles), compare it to something (another couple), branch on if some condition is met (another couple) and loop to repeat this (2 or 3 cycles). So you don't exactly have 15 cycles over.

AWOL: sp. "bit 2"

** Expletives deleted **###

Thank you. I will correct my post

...R

Indeed. True on both accounts. I dont have 15 cycles and its indeed another cross of the earlier post. I thought the earlier post threw people off topic as I was asking a more fundamental question which I have succeeded in this post.

I now need to do some math to see what can be done by my dear friend atmega 328p.

Indeed correct on both accounts @Nick

I realize that pin polling is not 1 clock cycle.

So, if I poll at 1 Mhz,

wait: sbis 0x09 ; 2cycles ;(2 cycles since instruction to skip next - rjmp is 1 word) rjmp wait ; 2 cycles

So waiting for a bit to be set on any port is 4 clock cycles. That leaves me 12 clock cycles to cycles to do everything else. Is that correct ?

@CodingBadly

Thanks for the python script, works very well + made it pep8 and pyflakes compliant + fixed a small bug (arduinoroot not defined when avr-objdump.exe already in path)

import fnmatch
import os
import subprocess

pathok = False
pathlist = os.environ['PATH'].split(os.pathsep)
for path in pathlist:
    testme = os.path.join(path, 'avr-objdump.exe')
    if os.path.exists(testme):
        pathok = True
        break

# arduinoroot = 'C:\\Arduino\\arduino-1.0.5\\'
# arduinoroot = 'C:\\Arduino\\arduino-1.6.5\\'
arduinoroot = 'C:\\Program Files (x86)\\Arduino\\'

if not(pathok):
    pathlist.append(arduinoroot + 'hardware\\tools\\avr\\utils\\bin')
    pathlist.append(arduinoroot + 'hardware\\tools\\avr\\bin')
    pathlist.append(arduinoroot + 'hardware\\tools\\avr\\etc')
    pathnew = os.pathsep.join(pathlist)
    os.environ['PATH'] = pathnew

os.chdir(arduinoroot)

tempdir = os.environ.get('TEMP')
tempfile = os.path.join(tempdir, 'Junk.cpp')

matches = []
for root,  dirnames,  filenames in os.walk(tempdir):
    for filename in fnmatch.filter(filenames,  '*.elf'):
        matches.append(os.path.join(root,  filename))

matches.sort(key=os.path.getmtime)

if len(matches) > 0:
    f = open(tempfile,  'w')
    # fix? Also include -j .bss -j .data -j .text ?
    subprocess.call(['avr-objdump.exe',
                     '-S',
                     '-z',
                     matches[len(matches)-1]
                     ],
                    stdout=f)
    f.close()
    os.system('start ' + tempfile)

abbanerjee:
Is that correct ?

No. Three cycles on false. Two cycles on true.

If the loop is preceded with a nop both paths are three cycles. (When precise cycles is important balanced conditionals is very handy.)

robtillaart:
Thanks for the python script, works very well

You are welcome.

  • made it pep8 and pyflakes compliant

I have no idea what those are. I will do some research.

  • fixed a small bug (arduinoroot not defined when avr-objdump.exe already in path)

Thanks.