【问题标题】:8-bit assembly programming, checking for palindrome8 位汇编编程,检查回文
【发布时间】:2016-12-09 18:33:18
【问题描述】:

所以,这里的第二个问题(这个问题很模糊),我被赋予的任务之一是创建一个检查回文的东西,然后如果是则显示是,如果不是则显示否。我的问题是,你将如何尝试实现它?我能想到让它工作的唯一方法是遍历字符串,计算字符,总数的一半以便找到单词的中间,然后递增 1 递减 1,然后比较两个字符看看它们是否相同(然后递减 2,3,依此类推,直到到达字符串的末尾。)。我曾尝试实施但不知道如何实施。

因此,如果任何人都可以给我任何很棒的指示,我将留下一个链接,指向我正在使用的 8 位模拟器以及我目前拥有的(这只是代码打印是/否 ATM。)

代码:

JMP begin
input: DB "PALINDROMEEMORDNILAP"
DB 0
begin:
    MOV C, input    ;Points to var input
    MOV D, 232  ;Points to output
    CALL check  ;Skips to check
    HLT

check:


       ;This is where my method of checking whether it is or isn't a 
       ;palindrome would go

.NO:
    MOV C, NO   ; Points to var NO
    MOV A, [C]  ; Gets first char
    MOV [D], A  ; Write to output
    INC D  
    JMP .NO2

.NO2:
    MOV C, NO
    INC C       ; Increments the char that it is pointing to in var NO
    MOV A, [C]  ; Gets second char
    MOV [D], A  ; Write to output
    RET     ; Terminates

.YES:
    MOV C, YES  ;Points to var YES
    MOV A, [C]  ; Gets first char
    MOV [D], A  ; Puts 1st letter in output
    INC D       ; Increments D so it doesn't overwrite
    JMP .YES2

.YES2:
    MOV C, YES
    INC C       ; Increments the char that it is pointing to in var YES
    MOV A, [C]  ; Gets second char
    MOV [D], A  ; Puts 2nd letter in output
    INC D  
    JMP .YES3

.YES3:
    MOV C, YES
    INC C       ;Increments the char that it is pointing to in var YES
    INC C
    MOV A, [C]  ; Gets third char
    MOV [D], A  ; Puts 3rd letter in output
    RET     ; Terminates

YES: DB  "YES" ; Var for yes
NO:  DB "NO"  ; Var for no

模拟器链接:http://schweigi.github.io/assembler-simulator/

任何帮助/指针/建议都会很棒。

提前致谢!

【问题讨论】:

  • 从优化您的打印​​程序开始——它们太“天真”了 尝试使用循环并编写一个通用程序来打印单词。当您实现它时,您将更容易编写回文程序。
  • 只需做人类所做的事情:检查第一个字符与最后一个字符,第二个字符与倒数第二个字符,依此类推。直到您没有更多的字符要检查,或者您正在检查一个字符本身。换句话说:str[0] == str[len-1-0], str[1] == str[len-1-1], str[2] == str[len-1-2],。 ..你看到模式了吗?

标签: assembly 8-bit


【解决方案1】:

好吧,看起来您可能错过了打印 hello world 示例的工作原理,以及为什么它们在字符串末尾定义零字节。随后导致您使用固定代码(3 字节副本或 2 字节副本)打印它。

尝试更多地了解示例“hello world”的工作原理,例如切换 CD 的突出显示以查看它们如何用作指向内存的指针。

在“step”执行之前尝试阅读指令描述,然后尝试猜测所有值将如何变化,然后运行“step”。然后试着找出任何差异,如果你没有猜对,你的错误是什么。


我修改了 hello world 加上您未完成的代码并使用了一些不同的结构,因此您可以尝试将其理解为下一个任务(它将打印“YES”,就好像输入是回文一样,但它根本不检查,它只是设置了check 的假“结果”,然后是 YES/NO 输出:

    MOV C, input    ;Points to var input
    CALL check  ; call check palindrome routine
    HLT

check:
    ; TODO palindrome check ... later ;)
    ; output: A = 0 when "NO", else "YES"

    MOV A, 123  ; fake result, try also "MOV A, 0"
    ; print result to output
    MOV D, 232  ; Points to output
    MOV C, YES  ; Point to string "YES"
    OR  A, A
    JNZ printYes ; when palindrome, C is correct
    ; print "NO" when not palindrome, modify C pointer
    MOV C, NO   ; Point to string "NO"
printYes:
    CALL print  ; reuse universal print subroutine to print YES/NO
    RET         ; exit check subroutine

print:      ; print(C:*from, D:*to), will print also last zero!
    PUSH A
.printLoop:
    MOV A, [C]  ; Get char from var
    MOV [D], A  ; Write char to output
    INC C       ; next source char
    INC D       ; next output cell
    OR  A, A    ; test if char is zero
    JNZ .printLoop
    POP A
    RET

; data defined after code, so I don't have to jump around them

YES: DB  "YES"
     DB  0
NO:  DB 78      ; ASCII 'N' in decimal
     DB 0x4F    ; ASCII 'O' in hexadecimal
     DB 0
input:
     DB "PALINDROMEEMORDNILAP"
     DB 0

label_to_see_length_of_code:

如果您掌握了所有这些,您现在应该能够处理输入字符串中的特定字母,并对它们进行一些测试。因此,首先编写子程序来计算字符串的长度,或者将“指针”返回到最后一个字符(在零终止符之前)。再次调试,直到它可以工作。

然后当你有这个指针时,用指向第一个字符的指针(MOV <some spare register>,input)加载其他寄存器。

那么回文校验算法可以是这样的:

    isPalindrome = 1
checkLoop:
    compare pointer to first char with pointer to last char
    => when (first_ptr >= last_ptr) jump to checkEnd
    load character from first_ptr
    load character from last_ptr
    inc  first_ptr
    dec  last_ptr
    compare two characters
    => when equal, loop to checkLoop
    isPalindrome = 0
checkEnd:

...嗯..现在我看到您将用完这个寄存器...好吧,补救措施对我来说很简单,但我会让您自己解决它,有多种策略:

  • 使用内存作为进一步的存储,来回​​加载/存储值到寄存器中有点慢

  • 优化算法以减少寄存器(可以只加载一个字符并将其与指针中的内存进行比较,但是您必须使零标志在指针更新后仍然存在,按此顺序这是不可能的.. . 但是先更新指针然后检查 char 会起作用,但这意味着指针已经指向不同的 char .. 那么即使它们已经更新,你能不能让它们指向正确的 char 呢?)。

【讨论】:

  • 顺便说一句,我的代码比你的短 30 个字节(74 个字节对 104 个字节),尝试通过使用 CALL 或避免无用的 @987654328 来了解我如何重用大量代码@ 指令(就像你的 JMP .NO2 跳转到下一条指令,无论如何 CPU 都会降落,因为它正在执行来自 IP 指针的指令)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 2019-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多