1

我正在写汇编,技术上是 HLA(高级汇编)并且在分配任务时遇到了麻烦。这是作业:


编写一个 HLA 汇编语言程序,计算圣莫尼卡学院的学生入学费用。(由于我们只知道如何处理整数运算,我们的程序会稍微不准确)。截至 2014 年秋季,居民的注册费为 46 美元/单元,所有其他人的注册费为 335 美元/单元。冬季或夏季的学生服务费为 48 美元,秋季或春季为 51 美元。停车贴的购买是可选的,秋季/春季价格为 85 美元,冬季/夏季价格为 45 美元。

注册费将根据用户输入的单个 8 位值输入。费用的格式为:prsseeee,其中 ss 是对应学期的两位值(秋季为 00,冬季为 01,春季为 10 或夏季为 11),eeee 是与数字对应的四位值在注册单位中,r 是对应于学生是否是加利福尼亚居民的单个位,p 是对应于是否需要停车贴花的单个位。该位域的格式如下图所示:

Packed Bit Field of Fees 由于只输入了 8 位,因此您的程序应该期望读取 2 个十六进制数字。

下面是一些演示这些想法的示例程序对话。(提示:一点一点地执行此操作。有很多内容......) (进一步提示:此任务的最重要部分是使用用户输入的打包数据字段来提取子-parts out of it. Intel 寄存器的重叠设计可帮助您解析此类数据字段,并且您可以移动位以将正确的部分转换为 BH 或 BL,例如......)(进一步提示:您可以通过直接读入寄存器来读取十六进制数字。)(最后提示:由于我们还没有学会如何做乘法,虽然它有点痛苦,但我希望你会通过一组循环加法指令来执行乘法)

喂我(2 个十六进制数字和 prsseeee 位):CC
秋季学期
12 个单位
CA 居民
停车
总费用 = 688 美元

喂我(2 个十六进制数字,带有 prsseeee 位):4C
秋季学期
12 个单位
CA 居民
禁止停车
总费用 = 603 美元

喂我(2 个十六进制数字与位 prsseeee):8C
秋季学期
12 个单位
非居民
停车
总费用 = 4156 美元


喂我(2 个十六进制数字与位 prsseeee):0C
秋季学期
12 个单位
非居民
禁止停车
总费用 = $ 4071

喂我(2 个十六进制数字与位 prsseeee):D1
冬季学期
1 单元
CA 居民
停车
总费用 = 139 美元

喂我(2 个十六进制数字与位 prsseeee):91
冬季学期
1 单元
非居民
停车
总费用 = 428 美元


这是我的代码:

program SMCFee;
#include( "stdlib.hhf" );
 static
   total : int32 := 0;

   begin SMCFee;

   stdout.put("Feed me(2 hex digits with the bits prsseeee):");
   stdin.get(BL);
   mov(total,EAX);
   mov(BL,AL);
   shr(4,AL);
   and( %0000_0011, AL );
   cmp(AL, 00);
   je Fall;
   cmp(AL, 10);
   je Spring;
   jmp Win;

   Fall:
   stdout.put("Fall Semester", nl);
       mov(BL,AL);
       shr(7,AL);
       and( %0000_0001, AL );
       cmp(AL,1);
       je SprFallPark;
       add(51, EAX);
       jmp ResCheck;

   Spring:
        stdout.put("Spring Semester", nl);
        mov(BL,AL);
        shr(7,AL);
        and( %0000_0001, AL );
        cmp(AL,1);
        je SprFallPark;
        stdout.put("No parking", nl);
        add(51, EAX);
        jmp ResCheck;

   SprFallPark:
        stdout.put("Parking", nl);
       add(136, EAX);
       jmp ResCheck;

   Win:
        cmp(AL, 11);
        je Summer;
        stdout.put("Winter Semester", nl);
       mov(BL,AL);
       shr(7,AL);
       and( %0000_0001, AL );
       cmp(AL,1);
       je WinSumPark;
       stdout.put("No Parking", nl);
       add(51, EAX);
       jmp ResCheck;

       Summer:
       stdout.put("Summer Semester", nl);
       mov(BL,AL);
       shr(7,AL);
       and( %0000_0001, AL );
       cmp(AL,1);
       je WinSumPark;
       stdout.put("No parking");
       add(51, EAX);
       jmp ResCheck;
   WinSumPark:
        stdout.put("Parking", nl);
       add(133, EAX);
       jmp ResCheck;

   ResCheck:
       mov(BL,AL);
       shr(6,AL);
       and( %0000_0001, AL );
       cmp(AL,1);
       je Res;
       stdout.put("Non-Resident", nl);
       mov(335,EDX);
       jmp CalcUnits;
   Res:
        stdout.put("CA Resident", nl);
       mov(46,EDX);
       jmp CalcUnits;

   CalcUnits:

   ForLp:
   mov(BL, AL);
   and(%0000_1111, AL);
   stdout.puti8(AL);
   stdout.put(" units", nl);
   ForLpTerminationTest:
   cmp(AL, 0);
   jle ForLpDone;
   ForLpBody:
   add(EDX, EAX);
   ForLpDecrement:
   dec(AL);
   jmp ForLpTerminationTest;
   ForLpDone:

   stdout.put("Total Fees = $");
   stdout.puti32(EAX);

   end SMCFee;

这一定是一些逻辑问题,比如说我输入了cc。它打印出正确的字符串,但总量是错误的。如果我输入 4c,我会得到正确的字符串,但停车除外。它完全跳过了,总数也是错误的。谢谢你的帮助。

编辑:这是我输入 CC 时结果的图片。如您所见,它正确键入了类别,但没有得到相同的结果。我相信我的问题是我如何拥有声明标签。 控制台窗口结果

4

1 回答 1

4

因此,Michael Petch 的评论解决了这个问题。问题是我正在写入 AL 和 AH,它们正在将数据破坏到 EAX 中。我将“总”寄存器更改为 ECX。一旦我这样做了,那只是我如何添加费用的一些小错误,然后它就可以正常工作了。

于 2015-11-21T05:54:41.970 回答