8位汇编编程,检查回文

时间:2016-12-09 18:33:19

标签: assembly 8-bit

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

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

CODE:

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/

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

提前致谢!

1 个答案:

答案 0 :(得分:0)

好吧,看起来您可能错过了示例打印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,即使它们已经更新了吗?)。