Assembly 在ARM汇编中使用C函数

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?我知道每当调用一个子例程时

我见过一些人在代码中使用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?我知道每当调用一个子例程时,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刚刚读取的数据
压敏电阻