ARM Assembly - 将输入文件更改为仅包含大写字母和空格,写入输出
ARM Assembly - Change input file to only include capital letters and spaces, write to output
我现在正在学习 x86 class,我们有一个 ARM 汇编作业,它是我们所做的 x86 作业的副本。基本上它从文件中读入,将小写字母更改为大写字母,并保留空格。所以它只写大写字母(如果是小写字母则更改小写字母),并复制空格,同时删除数字和字符。我们只使用十六进制字符 00h-7F(即使我们拥有的最低可用字符是 0x20)。我试图将我的代码从 x86 转换为 ARM,但它只是直接通过,没有写入输出。任何想法为什么,以及如何解决它?
我写了标记为 "check if lowercase" "check if uppercase" 和 "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
你的代码有很多问题,你应该先制作伪代码或流程图来弄清楚算法。
类似于:
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);
}
现在,将其转换为汇编代码是一件简单的事情。类似于:
_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
小心上面代码中的错误,我没有测试过:)
PS:从上到下的区别是 0x20 而不是 20,在您的代码中是 0x14。
我现在正在学习 x86 class,我们有一个 ARM 汇编作业,它是我们所做的 x86 作业的副本。基本上它从文件中读入,将小写字母更改为大写字母,并保留空格。所以它只写大写字母(如果是小写字母则更改小写字母),并复制空格,同时删除数字和字符。我们只使用十六进制字符 00h-7F(即使我们拥有的最低可用字符是 0x20)。我试图将我的代码从 x86 转换为 ARM,但它只是直接通过,没有写入输出。任何想法为什么,以及如何解决它?
我写了标记为 "check if lowercase" "check if uppercase" 和 "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
你的代码有很多问题,你应该先制作伪代码或流程图来弄清楚算法。
类似于:
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);
}
现在,将其转换为汇编代码是一件简单的事情。类似于:
_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
小心上面代码中的错误,我没有测试过:)
PS:从上到下的区别是 0x20 而不是 20,在您的代码中是 0x14。