Assembly 在ARM汇编中使用C函数
我见过一些人在代码中使用C库中的printf的例子,如下所示:Assembly 在ARM汇编中使用C函数,assembly,arm,calling-convention,Assembly,Arm,Calling Convention,我见过一些人在代码中使用C库中的printf的例子,如下所示: .data .balign 4 hello: .asciz "Hello\n" .text .global main .func main main: ldr r0, hello_msg bl printf mov r7, #1 swi 0 hello_msg: .word hello .global printf 他们怎么知道r0会作为字符串arg传递给printf?我知道每当调用一个子例程时
.data
.balign 4
hello: .asciz "Hello\n"
.text
.global main
.func main
main:
ldr r0, hello_msg
bl printf
mov r7, #1
swi 0
hello_msg: .word hello
.global printf
他们怎么知道r0会作为字符串arg传递给printf?我知道每当调用一个子例程时,r0-r3都作为arg传递,但我不知道哪个寄存器映射到哪个arg。示例:使用scanf时,r0是字符串格式,r1存储用户输入。我们怎么知道这些?我唯一的猜测是用gcc使用-s选项编译我的*.s文件,并查看组装好的文件。。。但是有更好的办法吗 我会尽力解释我学到的东西。我唯一拥有的Linux是RaspbianJessie(RaspberryPi3)。有一个文件/usr/include/arm-linux-gnueabihf/asm/unistd.h(其他linux应该在某个地方有unistd.h)显示了为内置到linux中的函数定义[ex:#define u NR_write(u NR_SYSCALL_BASE+4)]。查看Linux手册页的格式
ssize_t write(int fildes, const void *buf, size_t nbyte)
return in r0 [4] ( r0 , r1 , r2 )
我在这方面是新手,所以我加入了一个帮助我理解它的程序。有关其他格式,请参见
@----------------------------------
@ 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
@----------------------------------
@asfileio.s
@
@Raspbian-Jessie汇编程序使用
@用于Raspberry Pi 3上的文件操作的SVC
@
@ 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/测试*
@你好,世界
@一只敏捷的棕色狐狸跳过了那只懒狗。
@ 0
@-rw-r--r--1 pi 26 Jun 18 14:58/tmp/testfile01.txt
@-rw-r--r--1 pi 45 Jun 18 14:58/tmp/testfile02.txt
@ pi@RPi:~/程序$
@----------------------------------
@
@ http://man7.org/linux/man-pages/dir_by_project.html#man-页数
@
@CREATE int creat(常量字符*路径名,模式);
@模式rwx{所有者、组、其他}
@打开整型打开(常量字符*路径名,整型标志);
@O_RDONLY、O_WRONLY或O_RDWR标志
@| O|u
@读取ssize\u t读取(整型fd,无效*buf,大小\u t计数);
@写入大小写入(int-fd,const-void*buf,size\u-t-count);
@关闭int CLOSE(int fd);
@同步无效同步(void);
@退出无效_退出(int状态);
@
@----------------------------------
.数据
@请参阅/usr/include/arm-linux-gnueabihf/asm/unistd.h
@请参阅/usr/include/arm-linux-gnueabihf/bits/fcntl-linux.h
.equ创建,8
.equ模式,0644@-rw-r--r--
.平等公开赛,5
.equ路,00号
.equ Wr,01
.equ RdWr,02
.equ Apnd,02000
.equ read,3
.equ write,4
.equ close,6
.equ sync,36
.equ出口,1
.equ sfile,187
@----------------------------------
巴利格先生4
创建:
.word目录文件,模式,创建
巴利格先生4
开放式:
.word目录文件,RdWr | Apnd,打开
巴利格先生4
写:
.word数据,在_数据之后-数据,写入
巴利格先生4
第2条:
.word data2,在_data2-data2之后写入
巴利格先生4
阅读:
.单词Buf,80,读
巴利格先生4
缓冲器:
.空间80
@----------------------------------
数据:
.asciz“你好,世界”\n
数据之后:
巴利格先生4
数据2:
.asciz“一只敏捷的棕色狐狸跳过了那只懒狗。\n”
数据2之后:
巴利格先生4
目录文件:
.asciz“/tmp/testfile01.txt”
@----------------------------------
.文本
.global main,_start
@_开始:@如果使用ld作为链接器,则取消提交
主要内容:
推送{r4,r5,r7,lr}
b M_课程
S_Write:@err 4 if error@子程序或函数
@写入文件(或标准输出)的系统调用
@写入金额\写入=(写入(fd,&data,sizeof(data)))
@r0=(r7=4(r0,r1=&data,r2=len(data)))
ldr r3,=写入@参数地址
S_书面文件2:
ldm r3,{r1,r2,r7}@load write参数
svc#0@Linux内核写入
检查金额=len时凸轮轴位置r0,r2
movne r0,#4@将错误代码设置为4
bne exit@exit if error
mov r0,#0@success
mov pc,lr@返回程序
S_Create:@err 8 if error
@Create fd=(创建(&dir_文件,-rw-r--r--))
@r0=(r7=8(r0=&dir_文件,r1=0644))
ldr r3,=创建
ldm r3,{r0,r1,r7}
svc#0
mov r4,r0@将fd保存在r4中
cmp r0,#3@如果小于3则错误
移动r0,#8
blt出口
mov r0,#0
移动个人计算机
S_Open:@err 5 if error
ldr r3,=打开
ldm r3,{r0,r1,r7}
svc#0
mov r4,r0
cmp r0,#3
移动r0,#5
blt出口
mov r0,#0
移动个人计算机
S_Close:@err 6 if error
mov r7,关闭
svc#0
cmp r0,#0
movne r0,#6
bne出口
移动个人计算机
S_改为:
ldr r3,=读取
ldm r3,{r1,r2,r7}
svc#0
移动个人计算机
M_计划:
@S_Write调用向标准输出写入
mov r0,#1@fd=1=stdout
bl S_Write
@在/tmp中创建、写入和关闭文件
bl S_Create@Create file
移动fd至r0时的移动r0、r4
bl S_Write@写入文件
移动fd至r0时的移动r0、r4
bl S_Close@关闭文件
@打开同一文件进行写附加
bl S_Open@Open file
移动fd至r0时的移动r0、r4
bl S_Write@写入文件
移动fd至r0时的移动r0、r4
bl S_Close@Close文件
@更改新文件的变量
ldr r3,=dir\u文件
加上r3,#12
ldr r2,[r3]
提高采收率r2,#0x30000
strr2[r3]
@创建新文件、写入并关闭
bl S_创建
mov r0,r4
ldr r3,=Write2
《基本法》第2条
mov r0,r4
bl S_关闭
@打开文件、读取、写入标准输出并关闭
bl S_公开赛
mov r0,r4
bl S_Read
移动r2,r0@r0已读取金额
mov r0,#1@fd=1=stdout
ldr r1,=Buf@addr刚刚读取的数据
压敏电阻