在ARM程序集

时间:2016-07-11 16:03:04

标签: arm

我见过人们在代码中使用来自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就作为args传递,但我不知道哪个寄存器映射到哪个arg。示例:使用scanf时,r0是字符串格式,r1存储用户输入。我们怎么知道这个?我唯一的猜测是使用-S选项使用gcc编译我的* .s文件并查看已组装的文件...但是有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

I will try to explain what I have learned. The only Linux that I have is Raspbian Jessie (Raspberry Pi 3). There is a file /usr/include/arm-linux-gnueabihf/asm/unistd.h (other Linux should have unistd.h somewhere) that shows define for functions build into Linux [ex: #define __NR_write (__NR_SYSCALL_BASE+ 4)]. Look at Linux Man Page http://man7.org/linux/man-pages/man3/write.3p.html at the format.

     ssize_t write(int fildes, const void *buf, size_t nbyte)
return in r0  [4] (      r0  ,            r1  ,       r2    )

I am kind of new at this, so I have included a program that helps me understand it. Also see http://man7.org/linux/man-pages/dir_by_project.html#man-pages for other formats.

@----------------------------------
@ 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

The best docs that I have found on arm registers are http://caxapa.ru/thumbs/656023/IHI0042F_aapcs.pdf page 14.