我将尝试解释我所学到的。我唯一拥有的 Linux 是 Raspbian Jessie (Raspberry Pi 3)。有一个文件 /usr/include/arm-linux-gnueabihf/asm/unistd.h (其他 Linux 应该有 unistd.h 某处)显示为 Linux 内置函数的定义 [例如:#define __NR_write (__NR_SYSCALL_BASE+ 4)]。查看 Linux 手册页 http://man7.org/linux/man-pages/man3/write.3p.html 的格式。
ssize_t write(int fildes, const void *buf, size_t nbyte)
return in r0 [4] ( r0 , r1 , r2 )
我对此有点陌生,所以我提供了一个帮助我理解它的程序。另请参阅http://man7.org/linux/man-pages/dir_by_project.html#man-pages 了解其他格式。
@----------------------------------
@ asfileio.s
@
@ Raspbian Jessie assembly program using
@ SVC for file operations on Raspberry Pi 3
@
@ pi@RPi:~/Programs $ as -o asfileio.o asfileio.s
@ pi@RPi:~/Programs $ gcc -o asfileio asfileio.o
@ pi@RPi:~/Programs $ ./asfileio; echo $?; ls -l /tmp/test*
@ Hello world
@ A quick brown fox jumped over the lazy dog.
@ 0
@ -rw-r--r-- 1 pi pi 26 Jun 18 14:58 /tmp/testfile01.txt
@ -rw-r--r-- 1 pi pi 45 Jun 18 14:58 /tmp/testfile02.txt
@ pi@RPi:~/Programs $
@----------------------------------
@
@ http://man7.org/linux/man-pages/dir_by_project.html#man-pages
@
@ CREATE int creat(const char *pathname, mode_t mode);
@ Mode rwx {owner, group, other}
@ OPEN int open(const char *pathname, int flags);
@ Flags O_RDONLY, O_WRONLY, or O_RDWR
@ | O_APPEND
@ READ ssize_t read(int fd, void *buf, size_t count);
@ WRITE ssize_t write(int fd, const void *buf, size_t count);
@ CLOSE int close(int fd);
@ SYNC void sync(void);
@ EXIT void _Exit(int status);
@
@----------------------------------
.data
@ See /usr/include/arm-linux-gnueabihf/asm/unistd.h
@ See /usr/include/arm-linux-gnueabihf/bits/fcntl-linux.h
.equ create, 8
.equ Mode, 0644 @ -rw-r--r--
.equ open, 5
.equ Rd, 00
.equ Wr, 01
.equ RdWr, 02
.equ Apnd, 02000
.equ read, 3
.equ write, 4
.equ close, 6
.equ sync, 36
.equ exit, 1
.equ sfile, 187
@----------------------------------
.balign 4
Create:
.word dir_file, Mode, create
.balign 4
Open:
.word dir_file, RdWr | Apnd, open
.balign 4
Write:
.word data, after_data - data, write
.balign 4
Write2:
.word data2, after_data2 - data2, write
.balign 4
Read:
.word Buf, 80, read
.balign 4
Buf:
.space 80
@----------------------------------
data:
.asciz "Hello world\n"
after_data:
.balign 4
data2:
.asciz "A quick brown fox jumped over the lazy dog.\n"
after_data2:
.balign 4
dir_file:
.asciz "/tmp/testfile01.txt"
@----------------------------------
.text
.global main, _start
@_start: @ Uncommit if using ld as linker
main:
push {r4, r5, r7, lr}
b M_Program
S_Write: @ err 4 if error @ subroutine or function
@ System call to write to file (or stdout)
@ Write amt_wrote=(write( fd, &data, sizeof(data)))
@ r0=(r7=4( r0, r1=&data, r2=len(data)))
ldr r3, =Write @ address of parameters
S_Write2:
ldm r3, {r1, r2, r7} @ load write parameters
svc #0 @ Linux kernel writes
cmp r0, r2 @ check amt = len
movne r0, #4 @ set error code to 4
bne exit @ exit if error
mov r0, #0 @ success
mov pc, lr @ return to program
S_Create: @ err 8 if error
@ Create fd=(creat( &dir_file, -rw-r--r--))
@ r0=(r7=8 (r0=&dir_file, r1=0644 ))
ldr r3, =Create
ldm r3, {r0, r1, r7}
svc #0
mov r4, r0 @ save fd in r4
cmp r0, #3 @ err if < 3
movlt r0, #8
blt exit
mov r0, #0
mov pc, lr
S_Open: @ err 5 if error
ldr r3, =Open
ldm r3, {r0, r1, r7}
svc #0
mov r4, r0
cmp r0, #3
movlt r0, #5
blt exit
mov r0, #0
mov pc, lr
S_Close: @ err 6 if error
mov r7, #close
svc #0
cmp r0, #0
movne r0, #6
bne exit
mov pc, lr
S_Read:
ldr r3, =Read
ldm r3, {r1, r2, r7}
svc #0
mov pc, lr
M_Program:
@ S_Write call to write to stdout
mov r0, #1 @ fd=1=stdout
bl S_Write
@ Create, write and close file in /tmp
bl S_Create @ create file
mov r0, r4 @ move fd to r0
bl S_Write @ write to file
mov r0, r4 @ move fd to r0
bl S_Close @ close the file
@ Open same file for write append
bl S_Open @ open file
mov r0, r4 @ move fd to r0
bl S_Write @ write to file
mov r0, r4 @ move fd to r0
bl S_Close @ close file
@ Change variables for new file
ldr r3, =dir_file
add r3, #12
ldr r2, [r3]
eor r2, #0x30000
str r2, [r3]
@ Create new file, write and close
bl S_Create
mov r0, r4
ldr r3, =Write2
bl S_Write2
mov r0, r4
bl S_Close
@ Open file, read, write to stdout and close
bl S_Open
mov r0, r4
bl S_Read
mov r2, r0 @ r0 has amt read
mov r0, #1 @ fd = 1 = stdout
ldr r1, =Buf @ addr data just read
mov r7, #write
svc #0
mov r0, r4
bl S_Close
exit:
pop {r4, r5, r7, lr}
bx lr @ Exit if use gcc as linker
@ mov r7, #1 @ Exit if use ld as linker
@ svc #0 @ Exit if use ld as linker
我在 arm 寄存器上找到的最佳文档是 http://caxapa.ru/thumbs/656023/IHI0042F_aapcs.pdf 第 14 页。