8051单片机反汇编指令集

Posted

技术标签:

【中文标题】8051单片机反汇编指令集【英文标题】:Disassemble instruction set for 8051 microcontroller 【发布时间】:2020-09-24 16:37:22 【问题描述】:

我有以下 8051 微控制器的十六进制操作码序列

785679107A247BFD7C347D407E51745568F869F96AFA6BFB6CFC6DFD6EFE

我发现这个 repo 将十六进制转换为指令序列https://github.com/anarcheuz/8051-disassembler。

使用它,我能够获得以下组装说明

x00000000:      37 38        MOV 38 (R0,#immed)
0x00000002:     35           ANL A,@R0
0x00000004:     37 39        MOV 39 (R1,#immed)
0x00000006:     31 30 37     JBC 3037 (bit,offset)
0x00000008:     37 41        MOV 41 (R2,#immed)
0x0000000a:     32 34        ADD 34 (A,#immed)
0x0000000c:     37 42        MOV 42 (R3,#immed)
0x0000000e:     46           MOV R5,A
0x00000010:     37 43        MOV 43 (R4,#immed)
0x00000012:     33 34        ADDC 34 (A,#immed)
0x00000014:     37 44        MOV 44 (R5,#immed)
0x00000016:     34 30        JC 30 (offset)
0x00000018:     37 45        MOV 45 (R6,#immed)
0x0000001a:     35 31        ACALL 31 (addr11)
0x0000001c:     37 34        MOV 34 (A,#immed)
0x0000001e:     35 35        ANL 35 (A,direct)
0x00000020:     36           XRL A,R0
0x00000022:     46           MOV R0,A
0x00000024:     36           XRL A,R1
0x00000026:     46           MOV R1,A
0x00000028:     36           XRL A,R2
0x0000002a:     46           MOV R2,A
0x0000002c:     36           XRL A,R3
0x0000002e:     46           MOV R3,A
0x00000030:     36           XRL A,R4
0x00000032:     46           MOV R4,A
0x00000034:     36           XRL A,R5
0x00000036:     46           MOV R5,A
0x00000038:     36           XRL A,R6
0x0000003a:     46           MOV R6,A

在 wikipedia 上有一个解释 https://en.wikipedia.org/wiki/Intel_MCS-51 操作的含义,但由于我在难以理解之前没有使用过组装或微控制器。

有人知道工作流程是什么,最后不同寄存器中的值是什么吗?

【问题讨论】:

可变长度指令集的正确反汇编应该以非线性的执行顺序进行。 首先您需要将机器代码正确地转换为可读的东西(汇编语言),然后逐条执行指令并在纸上或指令集模拟器上执行该操作,但这个任务看起来会更容易手工。 如果您在查找文档中的每个操作码时不知道该指令的含义,您可以查找其功能。 【参考方案1】:

手动操作更容易/更快,只需查看 8051 指令集参考。

78 56  mov r0,#0x56
79 10  mov r1,#0x10
7A 24  mov r2,#0x24
7B FD  mov r3,#0xFD
7C 34  mov r4,#0x34
7D 40  mov r5,#0x40
7E 51  mov r6,#0x51
74 55  A,#0x55
68     XRL A,R0

你可以再花五分钟完成剩下的。

【讨论】:

(正如彼得指出的那样,这看起来是一些奇怪的 ascii 字节值 0x78、0x56、0x79、0x10 等字符串)。我猜这是一个家庭作业(我为你做了太多的工作) 哦,那不是我一直在指出的,我没有注意到这一点。双重ASCII双重危险,很好发现。 绝对是 0x37、0x38、0x35、0x36...不是如何解释这些,但 0x78、0x56、0x79 等看起来是合理的。 OP 称它们为十六进制操作码。这听起来像是家庭作业,一半的任务是解释机器代码。除非这是老师/书的教学方式(并且学生每天都向他们解释),否则这就是典型的:一本非常糟糕的教科书/课程。如果这只是一个 hexdump 排序工具,那么这不一定是非典型输出,但你怎么知道你没有开始中间指令?信息不足。【参考方案2】:

这看起来像是 ASCII 字符串的反汇编,而不是它们所代表的二进制值!请注意,中间一列(机器码)都是 0x30..46,即'0''F' 的 ASCII 码。

例如你反汇编的前两个字节是37 38,它们是'7''8'的ASCII码,但你想要的是一个78字节。

在将其提供给反汇编程序之前,您需要将其十六进制转储为二进制文件。

【讨论】:

@old_timer: 0x37'7' 的 ASCII 码。不知道你的意思。 785679107A247BFD7C347D407E51745568F869F96AFA6BFB6CFC6DFD6EFE 不是一串 ascii 字符,当你用它们制作字节时,我认为你的意思是,如果代码是这样的话,肯定 0x37 可以被认为是 '7' 的 ascii。 啊,我看到中间的列是的,这不是机器代码,而是其他东西,ascii ... @old_timer:在我的答案中添加了一个示例,可以更轻松地查看问题。我之前的描述不是很清楚。 这是我的错,我误解了你的评论没有仔细阅读它,字符串看起来确实可能是 ascii,所以我检查了它,它有很多垃圾。【参考方案3】:

输入radare2(或其rizin 分支,但您必须调整binary names)。

$ rax2 -s 785679107A247BFD7C347D407E51745568F869F96AFA6BFB6CFC6DFD6EFE
xVyz$�|4@~QtUh�i�j�k�l�m�n�

$ rasm2 -a 8051 -d 785679107A247BFD7C347D407E51745568F869F96AFA6BFB6CFC6DFD6EFE
mov r0, #0x56
mov r1, #0x10
mov r2, #0x24
mov r3, #0xfd
mov r4, #0x34
mov r5, #0x40
mov r6, #0x51
mov a, #0x55
xrl a, r0
mov r0, a
xrl a, r1
mov r1, a
xrl a, r2
mov r2, a
xrl a, r3
mov r3, a
xrl a, r4
mov r4, a
xrl a, r5
mov r5, a
xrl a, r6
mov r6, a

关于工作流程和最终寄存器值,根据说明,笔和纸是学习的第一步。这里有点矫枉过正,但是对于更大的代码,你可以求助于仿真(unicorn 似乎不支持 8051,搜索引擎会让你知道替代方案)。

【讨论】:

以上是关于8051单片机反汇编指令集的主要内容,如果未能解决你的问题,请参考以下文章

求汇编指令集

汇编语言

(023) 关于51单片机的A5指令

ida Pro ARM指令集和Thumb指令集的切换

arm 汇编指令

汇编与反汇编