街机模拟游戏逆向工程(HACKROM)教程:[7]68K汇编寄存器

本文详细介绍了68000处理器中的数据寄存器(如d0-d7)和地址寄存器(如a0-a7),以及它们在程序中的作用,包括数据缓冲、地址存储和自增/自减功能。通过示例代码展示了带括号操作符如何影响内存地址而非寄存器本身。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在之前的章节中,我们测试了一些程序代码,代码中很常见的一些比如D0,D1,D2....A0,A1,A2......之类的代码。这些代码中的字符是告诉汇编程序,这里是指向一个寄存器。寄存器是处理器的内部也有一些存储的空间,不同类型处理器根据其设计结构和设计目的的不同,各自有着不同类型的寄存器。在寄存器中,因为与CPU联系密切,数据的移动,加减操作,读取写入要比任何其他的存储设备(比如高速缓存,内存,硬盘等) 效率更高,速度更快(但是由于是集成在处理器内部,造价更高,存储空间也更小)。

数据寄存器:

68000有8个数据寄存器:

d0, d1, d2, d3, d4, d5, d6, d7

数据寄存器寄存了将要写入的数据,或读取后的数据。它就像缓冲器,持有从内存复制的数据,以准备给处理器使用。每个寄存器都有四个字节大小的空间,比如:

d0        00 00 00 00

地址寄存器:

68000同时拥有8个地址寄存器:

a0, a1, a2, a3, a4, a5, a6, a7

和数据寄存器不同,地址寄存器不能进行单字节长度的读取操作,只能进行双字节或四字节的操作。

我们需要注意,有部份的指令只能操作数据寄存器,而不能操作地址寄存器。

地址寄存器是用来存储地址的,我们可以对地址寄存器进行读写操作。

带括号的地址寄存器:

我们在很多代码中,我们可能会看到比如:

move.l    #$10,a0
move.l    #$20,(a0)

这样的代码,当A0加了括号变成了(A0)的时候,这条指令不会把$20这个立即数放到A0寄存器,而是会把$20这个立即数放到A0寄存器所指向的地址中。

我们来测试一下这两句代码:

*-----------------------------------------------------------
* Title      :
* Written by :
* Date       :
* Description:
*-----------------------------------------------------------
    ORG    $1000
START:                  ; first instruction of program

* Put program code here
    move.l    #$10,a0
    move.l    #$20,(a0)

    SIMHALT             ; halt simulator

* Put variables and constants here

    END    START        ; last line of source

 要观察该程序运行结果,我们同时需要打开内存窗口:

并观察内存窗口中的地址$10的值为FF FF FF FF:

我们步进一次,观察A0

可以看到,第一句代码是直接改变了A0寄存器。

我们再步进一次,同时观察内存窗口的地址$10

可以看到,第二句代码是改变了A0寄存器数据所指向的地址的值。

所以,当我们看到带括号的代码,比如(a0),($6c+A0)之类的代码,该代码是告诉汇编程序,这里指向的是一个内存地址。

自增/自减

地址寄存器的另一个方便的功能是自增/自减功能。该功能的作用是,执行完该指令后,该寄存器的值会根据操作长度来对寄存器的值进行增加或减少。

move.l    #$20,(a0)+

把之前测试代码中的括号右边增加一个"+"符号,就是自增功能

move.l    #$20,-(a0)

而自减功能,是要在括号左边增加一个"-"符号。自减和自增的不同之处还有就是,自减操作是在指令操作源操作数之前进行"自减"。


我们可以测试并观察以下代码来更直观地了解自增和自减功能:

*-----------------------------------------------------------
* Title      :
* Written by :
* Date       :
* Description:
*-----------------------------------------------------------
    ORG    $1000
START:                  ; first instruction of program

* Put program code here
    move.l      #$10,a0            *a0=$10
    move.l      #$01,(a0)+         *(a0)=$00000001, a0=a0+4
    move.w      #$02,(a0)+         *(a0)=$0002,     a0=a0+2
    move.b      #$03,(a0)+         *(a0)=$03,       a0=a0+1
    
    move.l      #$20,a0            *a0=$20
    move.l      #$03,-(a0)         *a0=a0-4,        (a0)=$00000003   
    move.w      #$02,-(a0)         *a0=a0-2,        (a0)=$0002
    move.b      #$01,-(a0)         *a0=a0-1,        (a0)=$01

    SIMHALT             ; halt simulator

* Put variables and constants here

    END    START        ; last line of source

### ZZULIOJ Java 编程题解及资源 #### 题目解析与解决方案 对于ZZULIOJ平台上关于Java编程的问题,通常涉及基础算法、数据结构以及特定功能实现。下面是一个典型的例子,展示了如何处理学生信息查询问题。 假设有一个题目要求根据给定的学生列表(包括学号、姓名和三门课程的成绩),当用户提供一个学号时,程序应返回对应的完整记录;如果找不到匹配的学号,则输出"Not Found"。这个问题可以通过创建一个`Student`类来简化操作,并利用哈希表快速定位目标条目[^3]。 ```java import java.util.*; class Student { String id; String name; List<Integer> scores; public Student(String id, String name, List<Integer> scores) { this.id = id; this.name = name; this.scores = scores; } } public class Main { private static final Map<String, Student> studentMap = new HashMap<>(); public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 假设这里有多组测试用例输入 while (scanner.hasNext()) { int numberOfStudents = Integer.parseInt(scanner.nextLine()); for (int i = 0; i < numberOfStudents; ++i) { String line = scanner.nextLine(); String[] parts = line.split(" "); String id = parts[0]; String name = parts[1]; List<Integer> scores = Arrays.stream(parts).skip(2).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); studentMap.put(id, new Student(id, name, scores)); } String queryId = scanner.nextLine(); if (studentMap.containsKey(queryId)) { Student foundStudent = studentMap.get(queryId); System.out.println(foundStudent.id + " " + foundStudent.name + " " + String.join(" ", foundStudent.scores.stream().map(Object::toString).toArray(String[]::new))); } else { System.out.println("Not Found"); } } } } ``` 此代码片段定义了一个名为`Main`的应用程序入口点,在其中读取多行输入直到遇到文件结束标志EOF。每行代表一位学生的详细资料,之后再接收一次单独的ID作为查询条件。通过构建映射关系使得每次查找都能高效完成。 #### 资源推荐 为了更好地准备类似的竞赛或练习,建议访问官方文档和其他在线教程以加深理解: - **Oracle 官方文档**: 提供最权威的语言特性和API说明。 - **LeetCode 和 Codeforces**: 这两个网站提供了丰富的编程挑战赛题库,有助于提高解决问题的能力。 - **GitHub 上开源项目**: 学习他人编写的高质量代码可以极大地提升自己的技术水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

字节狂徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值