【发布时间】:2015-07-25 23:15:11
【问题描述】:
我现在正在学习 x86 课程,我们有一个 ARM 程序集作业,它是我们所做的 x86 作业的副本。基本上它从文件中读取,将小写字母更改为大写,并保留空格。所以它只写大写字母(如果是小写则更改小写字母),并复制空格,同时去掉数字和字符。我们只使用十六进制字符 00h-7F(即使我们拥有的最低可用字符是 0x20)。我试图将我的代码从 x86 转换为 ARM,但它只是直接通过,没有写入输出。任何想法为什么,以及如何解决它?
我写了标有“检查是否小写”“检查是否大写”和“检查是否空格”的部分
;---------------------------------------------------------------------
; 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
【问题讨论】:
-
您忘记将
String的字符实际加载到r1中。您将需要一个循环,因为您一次读取了 128 个字节。当然你应该使用从系统调用返回的数字,因为你可能得到的更少。 PS:学习使用调试器。 -
@Jester 你能解释一下怎么做吗?我正在上课,我们的老师根本没有给我们提供太多关于 ARM 的指令,因为它是一个 x86 汇编课程。
-
你访问内存中的东西似乎没有问题,你可以做比较和分支,那么你需要解释什么?
-
这是字符串的加载。我的导师给我们开了一个关于 ARM 组装笔记的笑话,所以很难弄清楚。我们有一个示例程序,它复制整个文件。我在我的基础上使用它并编写了将输出更改为原始帖子中指定的代码。我知道它非常初级,但是我的导师在提供帮助方面有多糟糕(或者缺乏提供帮助更像是它