Can somebody suggest me any disassembler for Atmel AVR 8-bit microcontrollers? There are opensource projects for this?
Thanx.
You can also use avr-objdump, a tool part of the avr-gcc toolset ( http://www.nongnu.org/avr-libc/ ). Ex:
avr-objdump -s -m <avr architecture> .d program.hex > program.dump
where <avr architecture> is found on http://www.nongnu.org/avr-libc/user-manual/using_tools.html
[plug]IDA Pro supports AVR disassembly[/plug]:
As for opensource, AVR GCC package includes a port of objdump, including disassembling functionality.
http://www.onlinedisassembler.com/odaweb/
Lots of platforms (AVR also) but Microchip (which you didn't need either) is missing.
Big plus is that it is web based.
Checkout vAVRdisasm.
AVRDisassembler is an open source (MIT) AVR / Arduino disassembler written in .NET Core (which means it can run on Windows, Mac, Linux). Apart from writing the disassembly to stdout, it can also emit a JSON dump (for interopability, analysis purposes).
Disclaimer: I am the author of said library.
I'm using avrdisas by Johannes Bauer. It works with dumped flash, rather than the .hex file or ELF.
Compiling the following :
.include "tn13def.inc"
ldi r16,1
out ddrb,r16 ; PB0 as output
sbiw r24,1 ; slight wait
brne PC-1
sbi pinb,pinb0 ; toggle
rjmp PC-3 ; forever
produces listing:
C:000000 e001 ldi r16,1
C:000001 bb07 out ddrb,r16 ; PB0 as output
C:000002 9701 sbiw r24,1 ; slight wait
C:000003 f7f1 brne PC-1
C:000004 9ab0 sbi pinb,pinb0 ; toggle
C:000005 cffc rjmp PC-3 ; forever
extracting the flash contents with:
$ avrdude -p t13 -P usb -c usbtiny -U flash:r:flash.bin:r
gives: e001 bb07 9701 f7f1 9ab0 cffc
disassembly:
$ ./avrdisas -a1 -o1 -s1 flash.bin
; Disassembly of flash.bin (avr-gcc style)
.text
main:
0: 01 e0 ldi r16, 0x01 ; 1
2: 07 bb out 0x17, r16 ; 23
; Referenced from offset 0x06 by brne
; Referenced from offset 0x0a by rjmp
Label1:
4: 01 97 sbiw r24, 0x01 ; 1
6: f1 f7 brne Label1
8: b0 9a sbi 0x16, 0 ; 0x01 = 1
a: fc cf rjmp Label1
and this works for me, even if the endian-ness does not match the listing and I would need to resolve 0x17 back to DDRB etc.
As opensource disassembler I've tried Radare2 which is command-line oriented but you can also use the GUI called Cutter. https://rada.re/n/
Or you can just use the classical avr-objdump:
avr-objdump.exe -j .sec1 -d -m avr5 dumpfile.hex
Information source here
The question is rather about disassembling the HEX file and as a solution there are mentioned quite a lot tools above in other answers. Hard to add something more.
But if someone is looking for: it is also possible to disassemble the C/C++ while running in IDE. With Atmel studio with its integrated disassembling tool it can be done following way:
Run project (it can be run in simulator without debugger hardware);
Pause or stop at breakpoint;
Press CTRL + ALT + D
This can be useful in order to verify that particular code fragments are compiled as needed because the optimization sometimes skips/mangles the sequence and leads to some unexpected behavior.
Related
I am learning NASM x64 and searched for debugger. Not only did I try gdb, but SASM also. Unfortunately, they are both not viable options for me(*). According to
the issue (see comments section), it is possible to do debug NASM in Qt Creator. But i can't hit any breakpoints and see register values, for example.
Here my setup is:
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
enable_language(ASM_NASM)
project(untitled LANGUAGES C ASM_NASM)
SET(CMAKE_BUILD_TYPE Debug)
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F dwarf")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> \
<FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
add_executable(untilted main.c lab.asm)
set_target_properties(untilted PROPERTIES NASM_OBJ_FORMAT elf64)
main.c
extern void asm_main();
int main()
{
asm_main();
return 0;
}
lab.asm
bits 64
SYS_WRITE equ 1
STDOUT equ 1
NEW_LINE_CHARACTER equ 10
section .data
msg: db "Hello, World", NEW_LINE_CHARACTER, 0 ; length is 13
section .text
global asm_main
asm_main:
xor rax, rax
mov rax, SYS_WRITE
mov rdi, STDOUT
mov rsi, msg
mov rdx, 13
syscall
ret
Debugging main.c and i hit breakpoint
Can't hit breakpoint in lab.asm
So that's it. As you can see my build configuration is set to Debug(left down corner). So I would really appreciate any help with this issue.
*P.S yeah, probably, i am to lazy and not hardcore enough to use gdb 'cause i once did a lab in 600 lines in NASM and it was good but at the same time bad experience( it is better to learn c++ metaprogramming i dunno). Besides, it is a bit difficult to study and work when a russian drone or rocket can fly into your house, but as a ukrainian zoomer i am used to that kind of crap. I know that nobody asked to tell you that story, but i just want to finish my second year at university with systems programming done and be alive.
Since the Gameboy's processor, the LR35902, is a hybrid of the Z80 and the Intel 8080, keeping in mind that the Z80 and the Intel 8080 were designed to be mostly cross-compatible anyways, could anything that has a Z80 processor run opcodes that were meant for the LR35902? I was wondering not because I was hoping to use my TI84 to play Pokemon in study hall.
EDIT: I am aware that I would have to reprogram the controls, and probably the way that the game accesses RAM, but I'd rather just do that than port the whole game over.
The Z-80 instruction set is a superset of the 8080 instruction set. The LR35902 shares much in common with the 8080 but replaces some 8080 instructions with different ones and extends the instruction set in some different directions than the Z-80. The LR35902 is not compatible with the Z-80 nor is it compatible with the 8080.
You would have to find all uses of incompatible instructions and replace them with patches that provide the same functionality. Since the TI84 is much faster than the original GameBoy CPU the extra time taken will not be a problem and it will be easy to code replacements for the instructions themselves. The disassembly of the ROM and separating code from data will be time consuming.
However, you could take an existing GameBoy emulator and instrument it to record the locations of instructions it executes that are different on the Z-80. Playing the game extensively should find most of the places where the code must be patched.
For a quick overview see this chart of LR35902 instructions and compare with the Z-80. You'll also need this description of LR35902 instructions.
Here's a brief rundown instruction opcode differences between the LR35902 and the Z-80.
Opcode LR35902 Z-80
------ -------------- ----------
F2 LD A,(C) JP P,nn
E2 LD (C),A JP NV,nn
EA LD (nn),A JP V,nn
FA LD A,(nn) JP M,nn
3A LDD A,(HL) LD A,(nn)
32 LDD (HL),A LD (nn),A
2A LDI A,(HL) LD HL,(nn)
22 LDI (HL),A LD (nn),HL
08 LD (nn),SP EX AF,AF'
E0 LDH (n),A RET NV
F0 LDH A,(n) RET P
F8 LD HL,(SP+e) RET M
E8 ADD SP,e RET V
CB 3x SWAP r SL1 r (undocumented)
10 STOP DJNZ
D9 RETI EXX
It is a small help that LD A,(nn) and LD (nn),A are available on both and simply use different opcodes.
I have legacy code for an embedded 8051 core (in a cypress FX2) that used to compile with other versions of SDCC. However, current SDCC doesn't know the _naked qualifier:
delay.c:27: syntax error: token -> '_naked' ; column 21
as triggered by
static void
udelay1 (void) _naked
{
_asm ; lcall that got us here took 4 bus cycles
ret ; 4 bus cycles
_endasm;
}
and other occurrences.
As _naked practically is supposed to tell the C compiler to "nah, ignore the fact that you're a C compiler and understand that you'd need to save frame context", I don't feel like I should just #define it away.
Is there any solution to this? Should I just go ahead and manually inline the assembler wherever a _naked function is used? I feel like I'd betraying the compiler on a CALL there, and that would change the timing.
_naked was replaced by __naked in newer versions of SDCC. Same applies to asm/__asm, at/__at, interrupt,bit,xdata/__….
So, this turned out to be an exercise in regex replacements.
I'm still having linker/ranlib/mostly ar problems, and CMake ignores what I instruct it to use as compilers, but oh well.
I've wrote my very first MSP-EXP430F5529LP LED on/off program.
and I wanted to analyze my program. but I had problem at my first step.
I extracted my LED program from board and I've got unclear data. (3)
that's my first question. what is that file format? I mean I want to know file format for my memory dump file. (3)
my second question is that why CCS 6 doesn't indicate memory address properly?
I know that MSP430 is 16 bit MCU. so every memory address should be 16 bit-width. but my assembly code(2) which is copied from CCS6 Disassembly View show me address just like 01XXXX format.
relative data dereference and execution flow branches work well. but why CSS6 make me confused? I mean I want to know that why CCS6 display memory addresse 24 bit-width??
anyone who know where is TI document which explain what I want to know, please let me know. please just don't mention MSP430xxxx User's Guide.
sorry for my english :(
1.c code
#include <msp430f5529.h>
volatile unsigned int i;
void main(void) {
WDTCTL = WDTPW | WDTHOLD;
P1DIR |= 0x01;
while(1){
P1OUT ^= 0x01;
for(i = 20000;i > 0; i--);
}
}
2.assembly code
0100c2: 40B2 5A80 015C MOV.W #0x5a80,&Watchdog_Timer_WDTCTL
0100c8: D3D2 0204 BIS.B #1,&Port_A_PADIR
0100cc: E3D2 0202 XOR.B #1,&Port_A_PAOUT
0100d0: 40B2 4E20 2400 MOV.W #0x4e20,&i
0100d6: 3C02 JMP (0x00dc)
0100d8: 8392 2400 DEC.W &i
0100dc: 9382 2400 TST.W &i
0100e0: 27F5 JEQ (0x00cc)
0100e2: 3FFA JMP (0x00d8)
0100e4: 4303 NOP
0100e6: D032 0010 BIS.W #0x0010,SR
0100ea: 3FFD JMP (0x00e6)
0100ec: 431C MOV.W #1,R12
0100ee: 0110 RETA
0100f0: 4303 NOP
0100f2: 3FFF JMP (0x00f2)
3.memory dump (MAIN)
:1044000031400044b113ec000c930224b1130000be
:104410000c43b113c200b113f00000000200000011
:10442000840001001a44000000240000ffffffff89
:10443000ffffffffffffffffffffffffffffffff8c
:10444000ffffffffffffffffffffffffffffffff7c
...
...
If one reads the User Guide (which is why they exist) then one is informed that the Program Counter is 20-bit. So, now you know why you see an address in the 20-bit range.
Link to the MSP430 User Guide: http://www.ti.com/lit/ug/slau208n/slau208n.pdf
The 20-bit PC (PC/R0) points to the next instruction to be executed.
Each instruction uses an even number of bytes (2, 4, 6, or 8 bytes),
and the PC is incremented accordingly. Instruction accesses are
performed on word boundaries, and the PC is aligned to even addresses.
Figure 6-3 shows the PC.
The above is an excerpt from the User Guide. I cannot emphasis this enough - but you really need to read the User Guide. Not doing so and attempting to program microcontrollers is perlious to your mental health.
The memory dump seems to be in the Intel hex file format https://en.wikipedia.org/wiki/Intel_HEX
I have a program (not mine - downloaded from i-net) made on ATI streams (more accurate - on brook lang - file is *.br). There is a python script (see below), that compiles it into *.il file using brook compiler, provided by ATI streams SDK. After it script zips it into *.Z file. C-program's Makefile contains this code
my_kernel_dp11.o: my_kernel_dp11.Z
ld -s -r -o my_kernel_dp11.o -b binary my_kernel_dp11.Z
and then it linked to main executed file.
Data from that obj-file read by C-program into some buffer and then called calclCompile function (as I understand it's OpenCL func).
It works fine at AMD HD 6970-series, but failed at AMD HD 7970-series with following error
Unsupported program construct detected in back-end
Here is a python script
#!/usr/bin/python
import sys
import zlib
import os
def makebrz(dp_bits):
try:
os.unlink("a_slice_dpX_a_slicer.il")
except OSError:
pass
dpdefs=""
for i in range(dp_bits-11):
dpdefs = dpdefs + " -D DP_BIT_%i" % (i+12,)
print "DP_DEFS: ", dpdefs
os.system("/usr/local/atibrook/sdk/bin/brcc -k -pp %s a_slice_dpX.br" % (dpdefs,) )
f = open("a_slice_dpX_a_slicer.il")
if f==None:
print "Could not read ", sys.argv[1]
sys.exit(-1)
data = f.read()
f.close()
oname = "../my_kernel_dp%i.Z" % (dp_bits,)
data2 = zlib.compress(data)
fo = open( oname, "wb" )
fo.write(data2)
fo.close()
#os.system("ld -s -r -o ../%s.o -b binary %s" % (oname[:-2],oname))
makebrz(11)
makebrz(12)
makebrz(13)
makebrz(14)
And here is a program http://dl.dropbox.com/u/46469564/a_slice_dpX.br
The question is: what should I do to make it program "supported" ?
P.S. There is one problem - I don't know this technology (brook, ATI streams, OpenCL) at all. That's why advice like "you should try this or that" are useless. I need particular action to do - change this and you'll have a success :)
Thank you.
AFAIK Radeon HD7970 is built on GCN architecture, so if you are using brook to generate IL code, JIT in southern island may not know how to generate proper ISA for the h/w you are using,so if you would like continue using brook+ then you need to wait till an updated version of Brook+ gets released on sourceforge which can generate an IL which gets converted to right ISA(GCN).
Other option is to use AMD APP SDK 2.6 and rewrite your code in OpenCL.