0

我有一个大学作业。我需要为 z80 处理器编写一个汇编程序。该程序应执行以下操作。

从 0201H 开始的 20 个连续内存地址中存储了 20 个数字。程序应首先检查存储在 0200H 中的数字。如果值为 0,则程序应按升序对数字进行排序,否则按降序排序。最后在排序结束后,程序应该计算这 20 个数字的平均值。

我知道这个问题不是根据网站的规则形成的,但我真的需要帮助。

4

2 回答 2

7

这是 Z-80 汇编语言的快速指南。把它想象成 C,但删除了大部分功能。从根本上说,您只有几个变量可以使用:

unsigned char A;
unsigned short BC, DE, HL, IX, IY;
unsigned char memory[65536];

没有结构,没有块,没有 for 或 while 循环和一种 mangled if。有goto哪个会跳转到一个标签。或者您可以call使用一个类似于子例程但不带参数并返回 void 的标签。我们总是可以从这些部分构建更多功能,但对于简单的程序,我们拥有的变量和一些部分memory[]就足够了。

您可以=用于分配,但有很多规则。例如,所有这些都是合法的:

A = memory[26];
memory[738] = A;
A = memory[BC];
memory[DE] = A;

但是您不能使用任何旧表达式,例如:

A = memory[BC + DE];

short变量可以分配给和分配,但memory[]因为它们比char它们自动拆分的要大。当您说它memory[15] = BC;认识到它不适合并代表您执行此操作时:

memory[15] = BC % 256;
memory[16] = BC / 256;

为了有用,当您说时会发生相反的情况BC = memory[15]

BC = memory[15] + memory[16] * 256;

更奇怪的是,您可以将这些高低部分BC独立地讨论为BC。但你不能这样做B = memory[25]。如果你想这样,你需要A在中间使用:

A = memory[25];
B = A;

DE可以处理为DandEHLas Hand L。但不是IXIY(好吧,不是合法的,但我们不要进入那个)。

所有变量都可以递增和递减。 A = A + 1或者A++如果你喜欢。 A = A - 1. 与BC, DE, HL, IX,B等相同C

你能做到D = D + 2吗?不!你必须做D++; D++;。说到数学,A很特别。您可以向其添加任何无符号字符或常量。或减去。有一些逻辑运算,例如,&但我们不必担心这些。您还可以添加或减去我们的任何变量,例如或。但是你不能加或减。这也必须分段完成。假设你想要:|^unsigned charDLmemory[]A = A + memory[84]

B = A; // save A
A = memory[84];
A = A + B;

是的,它会变得乏味。人们开始欣赏编译器。您还可以对 HL、IX 和 IY 进行加减运算,但在更有限的情况下:

HL = HL + BC;
HL = HL + DE;
HL = HL + HL;  // Same as HL = 2 * HL.
IX = IX + BC;
IX = IX + DE;
IX = IX + IX;
// And follow the same pattern for IY

乘法和除法呢?不,不支持。不过,使用循环和位移运算符,您可以设法模拟它们。或者效率较低,您可以通过重复加法和重复减法进行乘法运算。

但是,无论如何,循环呢?好吧,你可以用这样的东西填充内存:

HL = 9; // You can assign constants to all your variables, thankfully.
A = 0;
loop:
  memory[HL] = A;
  HL = HL + 1;
  goto loop;

我有没有提到你的程序住在memory[]? 不?嗯,它确实是个问题。如果你只想清除 10 个memory[],你会怎么做?这就是精神错乱的地方if。你想写这样的东西:

HL = 9;
A = 0;
B = 10;
loop:
  memory[HL] = A;
  HL++;
  B = B - 1;
  if (B == 0) goto loop

[哎呀,这是一个错误。应该是!= 0,但假装它是正确的;我懒得重新输入这一切。] 但if (B == 0)不是支持的东西。太复杂。但是有一个是goto loop if zero; 什么意思?好吧,每次你做数学运算时,处理器都会记住一些关于结果的事情。一种是结果是否为零。事实证明,我们可以简单地将其替换if为:

goto loop if zero;

我们将循环 10 次。我们甚至可以将代码概括为,例如,清除memory[]由 给出的多个条目C。如何?B只要它不等于,就向上计数并循环回来C。我们不能这样做if (B == C),但我们可以减去BC检查零结果,这是同样的事情。好吧,我们做不到C = C - B,只有A可以做到。循环看起来像这样:

loop:
  memory[HL] = 0; // turns out we can do this
  HL = HL + 1;
  B = B + 1;
  A = C;
  A = A - B;
  goto done if zero;
  goto loop;
done:

尴尬,但它会工作。设计师有些仁慈。goto如果结果不为零,您可以:

A = A - B;
goto loop if not zero;

如果结果小于或大于零,则允许进行一些其他测试。但是针对零的简单测试可以让我们走得更远。

特殊情况比比皆是。如果我们不小心写了这个怎么办:

loop:
  memory[HL] = 0;
  B = B - 1;
  HL = HL + 1;
  goto loop if not-zero;

看起来像一个错误,不是吗。我们不会进行B迭代,而是继续进行直到HL环绕到 0。但事实并非如此。当我们添加或减去一个短值时,HL它不会影响zero/not-zero条件。该代码将起作用。事实上,这被 Z-80 的设计者认为是一项功能。

如果你愿意的话,我将提到的唯一另一件事是函数调用或子例程。鉴于每件小事都必须拼写出来,您可以看到即使是一个将数字乘以 4 的简单函数也会很好。但是没有参数,也没有返回值。不能这么说B = mult4(B); 相反,我们只是设置了约定,我们决定专门使用哪些变量或内存位置来传递参数以及结果的去向。来电者然后想办法解决。我们可以定义一个乘以B4 并返回结果的子例程A

mult4:
  A = B;
  A = A + A; // that is, B * 2
  A = A + A; // B * 4, we're don!
  return;

如果我们不想乘以D4,我们会这样做:

B = D;
mult4();
D = A;

很公平。我们还必须记住 mult4() 清除了 in 的值,A因此如果需要,我们最好保存它。就此而言,我们自己必须用尽B全力才能打电话。如果我们需要这些变量,那么我们只需要找到某个地方将它们存放在memory[].

memory[20] = A; // can't forget A
B = D;
mult4();
D = A;
A = memory[20]; // back to what it was.

这就是 Z-80 汇编语言编程。哦,还有一堆其他的东西。而且您确实说所有话都带有口音,但是如果您查找有关 Z-80 汇编语言的信息,我相信您会明白的。这里有一些例子:

A = memory[4];               LD A,(4)
A = 3;                       LD A,3
memory[2] = A;               LD (2),A
A = A + B;                   ADD A,B
B = B + 1;                   INC B

祝你的任务好运。

于 2015-09-18T06:30:23.880 回答
1

Rodnay Zaks 的 Z80 编程对于任何使用 Z80 汇编代码的人来说都是必读的。经作者许可可下载。

顺便说一句,该书中包含的代码示例之一是冒泡排序,从上到下进行了解释。

Z80 CPU 主页上提供了更多 Z80 相关信息。

于 2015-09-18T07:12:01.073 回答