如何访问命令行参数 (./program arg1 arg2 arg3)

How to access the command line arguments (./program arg1 arg2 arg3)

我如何访问这些参数?我读到它们存储在 r1 中,但我无法访问它们。

例如,在这段代码中:

.global main

main:
        ldr     r2, [r1, #4]
        ldr     r0, [r2]
        bx      lr

如果我用 7 值执行程序:

./program 7
echo $?

我得到了55,也就是7的十进制ASCII表示

所以我尝试添加子行:

.global main

main:
        ldr     r2, [r1, #4]
        sub     r2,r2,#48        // to actually obtain 7
        ldr     r0, [r2]
        bx      lr

但是我得到了0。为什么?

编辑(有效):

.global main

main:
        ldr     r2, [r1,#4]
        ldr     r0, [r2]
        sub     r0, r0, #48
        bx      lr

但是我不明白的是,为什么我用r0而不是r2就不行呢?像这样:

.global main

main:
        ldr     r0, [r1,#4]
        sub     r0, r0, #48
        bx      lr

您传递的是字符串“7”作为参数,而不是值 7,您必须将其转换为二进制值。

记住,main函数的签名是int main(int argc, char** argv, char** envp).

即参数个数在r0,参数字符串数组指针在r1,环境zero-terminated字符串数组指针在r2。

为了检索“7”,您需要访问 argv1 - argv[0] 将是包含您正在执行的程序路径的 zero-terminated 字符串。

如果您将 1 传递给 9,则只需减去“0”或 0x30 即可得到 argv1.

中检索到的值

对于 '1'.. '9' 之外的其他值,您应该从汇编程序中调用 atoi() ,或者为了好玩而自己转换它。

Procedure Call Standard for the ARM Architecture 是了解如何从汇编调用 C 函数或反之亦然的好读物。

#include <stdio.h>
int main ( int argc, char *argv[] )
{
    printf("%d\n",argv);
    return(0);
}
so.c: In function ‘main’:
so.c:5:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘char **’ [-Wformat=]

这是你的第一个问题

#include <stdio.h>
int main ( int argc, char *argv[] )
{
    printf("%d\n",argv[1][0]);
    return(0);
}
./so 7
55

55 = 0x37

如果你已经过去了,这将是你的第二个问题

可以通过简单地要求编译器显示路径来解决第一个问题。

#include <stdio.h>
int main ( int argc, char *argv[] )
{
    return(argv[1][0]);
}

   0:   e5913004    ldr r3, [r1, #4]
   4:   e5d30000    ldrb    r0, [r3]
   8:   e12fff1e    bx  lr

想想 C 函数是如何调用的,然后将其转换为汇编。指向字符串的指针数组。

然后根据指令集,您可能在阶乘函数中遇到其他问题。

编辑:

.global main

main:
        ldr     r2, [r1, #4]   <--- address of the pointer to the string
        sub     r2,r2,#48  <---- hoses the pointer to the string
        ldr     r0, [r2] <---- who knows what this is reading
        bx      lr

查看编译器生成的代码(假设7是命令行第一个参数./so 7)

   0:   e5913004    ldr r3, [r1, #4] <---- pointer to string (param 1)
   4:   e5d30000    ldrb    r0, [r3] <---- get first byte in string
                             r0 now contains 0x37
                    ldrb    r0, [r3,#1] <----- If I added this line
                             r0 now contains 0x00 string termination
   8:   e12fff1e    bx  lr   

现在想想 Frant 的回答,如果字符串是某个基数(“7”、“0x123”、“68”等)中的某个数字,您如何将字符串转换为数字。