【发布时间】:2016-04-11 20:22:34
【问题描述】:
我先从代码开始:
.equ SWI_Open, 0x66 @ open a file
.equ SWI_Close, 0x68 @ close a file
.equ SWI_PrStr, 0x69 @ Write a null-ending string
.equ SWI_RdStr, 0x6a @ Read a string
.equ Stdout, 1 @ Set output target to be Stdout
.equ SWI_Exit, 0x11 @ Stop execution
.global _start
.text
_start:
ldr r0,=InFileName
mov r1,#0
swi SWI_Open
bcs InFileError
ldr r1,=InFileHandle
str r0,[r1]
mov r8, r0 @ r8 will hold the address of the file handle
ReadLoop:
mov r0, r8
ldr r1, =LineArray
mov r2, #256
swi SWI_RdStr
bcs EndReached
@ r1 now has address of the read line
mov r9, r1 @ r9 will hold the memory address of the read line
mov r4, #0 @ r4 = START
mov r5, #1 @ r5 = END
bl PerLineFunc @ r0/r1 args passed to PerLineFunc
@ ShuffleWord within PerLineFunc should change the words around, so now we just need to print the new line of words
mov r0, #Stdout
mov r1, r9
swi SWI_PrStr
ldr r1, =NL
swi SWI_PrStr
bal ReadLoop
SWI_RdStr 从给定文件中读取一行并将其存储到内存中,地址位置存储在 r1 中。我的问题是我不知道如何将读入行的内存归零。如果第一行是 20 个字符,下一行是 15 个字符,那么在读取第二行之后,第一行的最后 5 个字符还在内存中。
我在想它会是这样的:
ldr r1, =LineArray
str #0, [r1]
但这会返回语法错误...我只是想在再次运行 ReadLoop 之前重置内存。
编辑:在 OP 中发布答案。 这第一部分需要添加到 ReadLoop 的末尾
mov r0, #0
ldr r1, =LineArray
mov r2, #0
bl EraseMemory @ r0, r1, and r2 passed into EraseMemory
这里是 EraseMemory 函数
EraseMemory:
str r0, [r1]
add r1, r1, #4
add r2, r2, #1
cmp r2, #64 @ 256 / 4 = 64
bxeq lr @ This loop should run 64 times to erase all 256 bytes of memory that were used
bal EraseMemory
【问题讨论】:
-
固定 insn 大小的 RISC 机器在单个指令中没有空间容纳立即操作数和寻址模式 + 位移。即使您不使用位移(
[r1 + 100]或任何 ARM 语法),存储指令编码对位也有意义。 (这类事情是降低指令集复杂性的重点)。顺便说一句,尽可能避免重新加载常量。您可以将=NL加载到不同的注册表中,这样您就不会破坏=LineArray。 -
我不太明白你说的第一部分是什么意思。至于加载到寄存器中,我的印象是这样做是可以的,因为这些是内存中的位置。
=NL与=LineArray是不同的内存位置,因此将其加载到 r1 并不是什么大问题。程序的那部分实际上似乎工作得很好,我只是在使用后无法清除内存 -
我的意思是你似乎不止一次谈论将
=LineArray加载到r1中,不是吗?我是说您应该将=LineArray保存在寄存器中,而不是重新加载它。此外,如果NL在内存中接近LineArray,您可能会使用add r2, r1, #(NL - LineArray)或其他东西。请记住,ldr reg, =value是一个伪操作,它可以变成来自附近常量池的负载,而不是立即数。 -
第一部分解释了为什么
str #0, [r1]不可编码:str指令没有空间用于立即数,因为它使用所有空闲位来编码寻址模式和位移。它是 RISC,所以如果没有位移,位就为零,而不是可用于其他东西。