ARM 程序集 - 将输入文件更改为仅包含大写字母和空格,写入输出 [英] ARM Assembly - Change input file to only include capital letters and spaces, write to output
问题描述
我现在正在学习 x86 课程,我们有一个 ARM 汇编作业,它是我们所做的 x86 作业的副本.基本上它从文件中读取,将小写字母更改为大写字母,并保留空格.所以它只写大写字母(如果是小写就改变小写字母),并复制空格,同时去掉数字和字符.我们仅使用十六进制字符 00h-7F(即使我们拥有的最低可用字符是 0x20).我试图将我的代码从 x86 转换为 ARM,但它只是直接通过,没有写入输出.任何想法为什么,以及如何解决它?
I'm taking an x86 class right now, and we have an ARM assembly assignment, which is a copy of an x86 asssignment we did. Basically it reads in from a file, changes lowercase letters to uppercase, and keeps spaces. So it only writes capital letters (change the lowercase letters if they are lowercase), and copy the spaces, while getting rid of numbers and characters. We are using only hex characters 00h-7F (even though the lowest usable character we have is 0x20). I tried to convert my code from x86 to ARM but it just goes straight through, without writing to an output. Any Idea why, and how to fix it?
我写了标有检查是否小写"、检查是否大写"和检查是否有空格"的部分
I wrote the sections labeled "check if lowercase" "check if uppercase" and "check if space"
;---------------------------------------------------------------------
; File: ARMkey.s
;
; Function: This program copies an ASCII file
; It assumes the file uses CR/LF as the end of line sequence
; - It opens an input file named key.in
; - It opens an output file named key.out
; - It reads one line of text from the input file.
; - It writes that one line to the output file, only using chars 00h-7Fh then a CR LF
; - It loops until it reaches end of file
; - It closes the input and output file
;
;
;---------------------------------------------------------------------
;----------------------------------
; Software Interrupt values
;----------------------------------
.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 and terminate with null char
.equ SWI_Exit, 0x11 ;Stop execution
;----------------------------------
.global _start
.text
_start:
;----------------------------------
; open input file
; - r0 points to the file name
; - r1 0 for input
; - the open swi is 66h
; - after the open r0 will have the file handle
;----------------------------------
ldr r0, =InFileName ;r0 points to the file name
ldr r1, =0 ;r1 = 0 specifies the file is input
swi SWI_Open ;open the file ... r0 will be the file handle
ldr r1, =InFileHandle ;r1 points to handle location
str r0, [r1] ;store the file handle
;----------------------------------
;----------------------------------
; open output file
; - r0 points to the file name
; - r1 1 for output
; - the open swi is 66h
; - after the open r0 will have the file handle
;----------------------------------
ldr r0, =OutFileName ;r0 points to the file name
ldr r1, =1 ;r1 = 1 specifies the file is output
swi SWI_Open ;open the file ... r0 will be the file handle
ldr r1, =OutFileHandle ;r1 points to handle location
str r0, [r1] ;store the file handle
;----------------------------------
;----------------------------------
; read a string from the input file
; - r0 contains the file handle
; - r1 points to the input string buffer
; - r2 contains the max number of characters to read
; - the read swi is 6ah
; - the input string will be terminated with 0
;----------------------------------
_read: ;
ldr r0, =InFileHandle ;r0 points to the input file handle
ldr r0, [r0] ;r0 has the input file handle
ldr r1, =String ;r1 points to the input string
ldr r2, =128 ;r2 has the max size of the input string
swi SWI_RdStr ;read a string from the input file
cmp r0,#0 ;no characters read means EOF
beq _exit ;so close and exit
;----------------------------------
;----------------------------------
; Check if Lower Case Letter
;----------------------------------
cmp r1, #0x61 ;check against lowercase a
blt _notlower ;if less go to notlow
cmp r1, #0x7A ;check against lowercase z
bgt _notlower
sub r1, r1, #0x14 ;Make letter uppercase
bal _read
;----------------------------------
; Check if Upper Case Letter
;----------------------------------
_notlower:
cmp r1, #0x41 ;dl < A
blt _space ;jump to not letter
cmp r1, #0x5A ;dl > Z
blt _space ;jump to not letter
;----------------------------------
; Check if Space
;----------------------------------
_space:
cmp r1, #0x20 ; r1 = space?
beq _read ; yes, get new letter
;----------------------------------
; Write the outputs string
;----------------------------------
_write: ;
ldr r0, =OutFileHandle ;r0 points to the output file handle
ldr r0, [r0] ;r0 has the output file handle
ldr r1, =String ;r1 points to the output string
swi SWI_PrStr ;write the null terminated string
;
ldrb r1, [r1] ;get the first byte of the line
cmp r1, #0x1A ;if line was DOS eof then do not write CRLF
beq _read ;so do next read
;
ldr r1, =CRLF ;r1 points to the CRLF string
swi SWI_PrStr ;write the null terminated string
;
bal _read ;read the next line
;----------------------------------
;----------------------------------
; Close input and output files
; Terminate the program
;----------------------------------
_exit: ;
ldr r0, =InFileHandle ;r0 points to the input file handle
ldr r0, [r0] ;r0 has the input file handle
swi SWI_Close ;close the file
;
ldr r0, =OutFileHandle ;r0 points to the output file handle
ldr r0, [r0] ;r0 has the output file handle
swi SWI_Close ;close the file
;
swi SWI_Exit ;terminate the program
;----------------------------------
.data
;----------------------------------
InFileHandle: .skip 4 ;4 byte field to hold the input file handle
OutFileHandle: .skip 4 ;4 byte field to hold the output file handle
;
InFileName: .asciz "KEY.IN" ;Input file name, null terminated
;
String: .skip 128 ;reserve a 128 byte string
;
CRLF: .byte 13, 10, 0 ;CR LF
;
OutFileName: .asciz "KEY.OUT" ;Output file name, null terminated
;----------------------------------
.end
测试文件有以下字符:
!"#$%&'()*+,-/0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
abcdefghijklmnopqrstuvwxyz{|}~
它应该只输出:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
推荐答案
您的代码存在多个问题,您可能应该先制作伪代码或流程图以找出算法.
Multiple problems with your code, you should have probably made pseudocode or a flowchart first to figure out the algorithm.
类似于:
while(ReadString(String, 128) != 0)
{
for(r0 = r1 = String; *r0 != 0; r0++)
{
if (IsLower(*r0))
{
*r1++ = UpperCase(*r0);
} else if (IsUpper(*r0) || IsSpace(*r0)) {
*r1++ = *r0;
}
}
*r0 = 0; /* terminate */
WriteString(String);
}
现在,将其转换为汇编代码是一件简单的事情.类似的东西:
Now, it's a simple matter to turn that into assembly code. Something like:
_read:
ldr r0, =InFileHandle ;r0 points to the input file handle
ldr r0, [r0] ;r0 has the input file handle
ldr r1, =String ;r1 points to the input string
ldr r2, =128 ;r2 has the max size of the input string
swi SWI_RdStr ;read a string from the input file
cmp r0,#0 ;no characters read means EOF
beq _exit ;so close and exit
ldr r0, =String
mov r1, r0
charloop:
ldrb r2, [r0]
cmp r2, #0
beq endofstring
cmp r2, #'z'
bgt skip
cmp r2, #'a'
bge lower
cmp r2, #'Z'
bgt skip
cmp r2, #'A'
bge copy
cmp r2, #' '
beq copy
bal skip
lower:
sub r2, r2, #0x20
copy:
strb r2, [r1], #1
skip:
add r0, r0, #1
bal charloop
endofstring:
strb r2, [r1] ; copy the terminating zero
ldr r0, =OutFileHandle ;r0 points to the output file handle
ldr r0, [r0] ;r0 has the output file handle
ldr r1, =String ;r1 points to the output string
swi SWI_PrStr ;write the null terminated string
;
ldr r1, =CRLF ;r1 points to the CRLF string
swi SWI_PrStr ;write the null terminated string
;
bal _read ;read the next line
注意上面代码中的错误,我没有测试过:)
Beware of bugs in the above code, I haven't tested it :)
PS:从上到下的差异是 0x20,而不是 20,这在您的代码中是 0x14.
PS: the difference from upper to lower is 0x20 not 20 which would be 0x14 as in your code.
这篇关于ARM 程序集 - 将输入文件更改为仅包含大写字母和空格,写入输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!