所以,这里的第二个问题(这个很模糊),我给出的任务之一是创建一些检查回文的东西,然后显示是,如果是,如果不是,则显示。我的问题是,你将如何去做呢?我能想到使其工作的唯一方法是遍历字符串,计算字符,总数的一半以找到单词的中间,然后递增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/
任何帮助/指针/建议都会很棒。
提前致谢!
答案 0 :(得分:0)
好吧,看起来您可能错过了示例打印hello world的工作方式,以及为什么它们在字符串末尾定义了零字节。随后会引导您使用固定代码(3字节副本或2字节副本)进行打印。
尝试更多地了解“hello world”示例的工作原理,例如切换C
和D
的高亮显示,看看它们如何用作指向内存的指针。
尝试通过“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,即使它们已经更新了吗?)。