进入 ARGV 臂组件

Access ARGV Arm Assembly

我正在尝试获取 argv 的内容并显示它们。

该程序将被调用为 ./main 5 6 7

r0 = argc

r1 = argv[0]

r2 = argv[1]

这个程序正确地获取了命令行参数的数量,但它使用 r1 并打印一个字符串却不能正常工作。它打印根据参数数量变化的随机字符。

.text
.global main
.extern printf
main:
        push {ip, lr}
        mov r1, r0
        ldr r0, =string
        bl printf
        pop {ip, pc}

.data
string: .asciz "Argc: %d\n"

参数:

.text
.global main
.extern printf
main:
        push {ip, lr}
        mov r1, r2
        ldr r0, =string
        bl printf
        pop {ip, pc}

.data
string: .asciz "Argv: %s\n"

argv 是一个数组,作为单个参数而不是参数序列传递给 main。因此,C 中的 argv[0] 在 ARM 汇编中转换为 [r1]argv[1] 转换为 [r1,4]argv[2] 转换为 [r1,8],等等。每个数组元素的偏移量增加四个字节,因为 argv 是一个指针数组,这是普通的 ARM(不是 AArch64),所以指针是 32 位宽,即 4 个字节。

如果你改变

    mov r1, r2

    ldr r1, [r1, 4]

您的程序应该可以正常工作。

注意在调用printf之后还应该清除r0,这样mainreturns就为零,而不是垃圾。

您可能会发现 ARM Procedure Call Standard 有帮助。

这是我目前正在查看的一些反汇编的 ARM 代码。我只是想弄清楚 getopt 的用法。

; int __cdecl main(int argc, const char **argv, const char **envp)
EXPORT main
main

var_140= -0x140
var_13C= -0x13C
var_138= -0x138
var_130= -0x130
var_32= -0x32
var_30= -0x30
var_2C= -0x2C

STMFD           SP!, {R4-R11,LR}
SUB             SP, SP, #0x11C
MOV             R7, R0  ; R0 contains the argc.  See below
MOV             R6, R1  ; R1 contains the pointer to argv[]
MOV             R3, #0x1434B4
MOV             R5, #0

...some code in between...

MOV             R10, R5
MOV             R4, #aVvk ; "Vvk:" ; setting the shortopts below
ADD             R8, SP, #0x140+var_130
MOV             R9, #optarg ; EXPORT location for optarg
MOV             R11, R5
MOV             R5, #0x1434B4
B               loc_1026F4

loc_1026F4              ; getopt loop starts here
MOV             R0, R7  ; argc
MOV             R1, R6  ; argv
MOV             R2, R4  ; shortopts
BL              getopt  ; call getopt, passing R0, R1, and R2
CMN             R0, #1
BNE             loc_102684

...do the option checks and loop until done...

这看起来支持@zwol 的回答。
不知道如果我们有更多的论据而不是 R1 可以容纳的东西会发生什么。它是否刚开始使用 R2?