我试图获取argv的内容并显示它们。
该程序将被称为./main 5 6 7
。
r0 = argc
r1 = argv [0]
r2 = argv [1]
这个程序正确地获取了命令行参数的数量,但是通过使用r1并打印字符串它不会起作用。它会根据args的数量打印随机字符。
.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"
的argv:
.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"
答案 0 :(得分:3)
argv
是一个数组,作为单个参数传递给main
,而不是参数序列。因此,C中的argv[0]
会转换为ARM程序集中的[r1]
,argv[1]
转换为[r1,4]
,argv[2]
转换为[r1,8]
,依此类推。每个数组元素的偏移量增加4个字节,因为argv
是一个指针数组,这是普通的ARM(不是AArch64),因此指针是32位宽,即4个字节。
如果你改变了
mov r1, r2
到
ldr r1, [r1, 4]
你的程序应该正常工作。
请注意,您还应在调用r0
后清除printf
,以便main
返回零,而不是垃圾。
您可能会发现ARM Procedure Call Standard有帮助。
答案 1 :(得分:0)
以下是我目前正在研究的一些反汇编的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吗?