我会尽量缩短序言。
是的,这基本上是“帮助我完成我的大学作业”,但我非常坚持这一点(我们在10点,这里)。
目标 - 编写一个程序集程序,该程序将字符作为输入并将该字符输出为大写。
我已经查阅了教科书,通过电子邮件发送给我的教授(回复待定,但我就像一条带骨头的狗 - 我不能单独完成这项功课,直到完成),并尝试了我能想到的所有可能的排列。这个示例几乎与pep / 8帮助中包含的示例相同(我认为图6.34中的哪一个是布尔转换示例),除了字符存储在#1cs而不是#2d中。
无论如何,问题的核心是每当我尝试在uprcse函数中访问ch2时,程序就会从堆栈中获取返回地址。据我所知,我这样做与示例相同,不幸的是,找不到pep / 8的优秀在线资源(感谢Python,调用你的标准pep8 ......)所以我受限于我有多疯狂地谷歌。
请查看下面的代码并随意通过您自己的pep8运行它并告诉我我做错了什么。
请不要觉得需要进行堆栈溢出并指出代码中的每个小缺陷 - 我知道这可能在uprcse函数中分支不同。我的意思是,你可以给出一点修正,如果这是你得到你的踢/业力但是......呃。
BR main
;
;******* char uppercase(char ch)
retVal: .EQUATE 2 ;returned value #1c
ch2: .EQUATE 1 ;formal parameter #1c
uprcse: LDBYTEA ch2,sx ;if ((ch >= 'a')
if: CPA 'a',i
BRLT else
LDBYTEA ch2,s ; && (a <= 'z'))
CPA 'z',i
BRGT else
then: LDBYTEA ch2,s ; return changed
SUBA 'a',i
ADDA 'A',i
STBYTEA retVal,s
RET0
else: LDBYTEA ch2,d ; return unchanged
STBYTEA retVal,s
RET0
;******* main ()
ch: .EQUATE 0 ;local variable #1c
main: SUBSP 1,i ;allocate #ch
STRO msg0,d ;cout << "Enter character, Zack" << endl
CHARI ch,s ;cin >> ch
LDBYTEA ch,s
STBYTEA -2,s ;store the value of age
SUBSP 2,i ;push #retVal #ch2
CALL uprcse ;ch = (uppercase(ch)
ADDSP 2,i ;pop #ch2 #retVal
LDBYTEA -1,s ;load retVal
STBYTEA ch,s
CHARO ch,s ;cout << ch << endl
CHARO '\n',i
ADDSP 1,i ;deallocate #ch
STOP
msg0: .ASCII "Enter character\n\x00"
.END
答案 0 :(得分:0)
我要做那个stackoverflow的事情。遗憾。
在main
中,在阅读完字符后,您会犯一个小错误:
STBYTEA -2,s ;store the value of age
SUBSP 2,i ;push #retVal #ch2
存储到SP-2,然后从SP中减去2。这使您的代码容易受到中断导致的罕见问题的影响,其中中断可能会触发(在堆栈底部写入数据)然后返回,从而导致数据损坏。
当你在编写程序集时,你应该在实际使用你正在“分配”的内存之前进行帧调整。
在此代码中,
CALL uprcse ;ch = (uppercase(ch)
ADDSP 2,i ;pop #ch2 #retVal
LDBYTEA -1,s ;load retVal
STBYTEA ch,s
您可以执行相反的操作,在访问结果之前添加到SP。同样的理论也适用。在解除分配之前拔出数据。
CALL uprcse
LDBYTEA 0,s ; 0 because now return value is above SP
STBYTEA ch,s
ADDSP 2,i
在uprcse
函数中,我认为你有一个简单的算术错误:
;******* char uppercase(char ch)
retVal: .EQUATE 2 ;returned value #1c
ch2: .EQUATE 1 ;formal parameter #1c
uprcse: LDBYTEA ch2,sx ;if ((ch >= 'a')
在此代码中,您将ch2
定义为SP + 1。我认为你应该使用+2。此外,您可以通过调整堆栈框架立即包含本地存储来简化您的生活:
ch: .EQUATE 4 ; formal parameter `ch` #1c
;old-sp .EQUATE 2 ; 2 bytes for return address
temp .EQUATE 0 ; Not actually used, just to show locals
uprcse: SUBSP 2,i ; Adjust stack frame for locals
LDA ch,s
请注意,在大多数计算机上(并非全部!),“比较”操作是“减法”的同义词。有时它是“减去但不存储”。其他时候它是“减去并确保设置标志”。但总的来说,减法和比较经常是相关的。你可以利用这个优势:
CPA 'a',i
BRLT else
此时,A寄存器包含ch-'a'。而不是重新加载A并比较'z',你可以比较'z' - 'a'(25):
CPA 25,i
BRGT else
最后,ASCII被设计(故意!),大写和小写字母之间有32个字符。这使得小写只有一个+ + 32。或者你可以设置32位。同样,要从低到高,只需减去32,或清除32位。
LDBYTEA ch2,s
SUB 32,i
STBYTEA ch2,s
else:
RET2 ; Remember temp?
在这种情况下,我假设您可以重新使用ch2
形式参数的存储作为返回结果。特别是因为结果与ch2
相同,除非它是小写的,在这种情况下我们会调整它。
答案 1 :(得分:0)
一切!跟进这篇文章。
我和教授谈过,他澄清了我的错误 -
我犯的错误是我没有在.EQUATE中为大写函数设置正确的值。我本应该使用2和3作为值而不是1和2.我还需要使用LDA 0x0000清除累加器,i在大写函数的开头。当这个作业被关闭和评分时,我会发布整个工作源代码。