Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 进入ARGV臂组件_Assembly_Arm_Argv - Fatal编程技术网

Assembly 进入ARGV臂组件

Assembly 进入ARGV臂组件,assembly,arm,argv,Assembly,Arm,Argv,我正在尝试获取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

我正在尝试获取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"
Argv:


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

如果你改变

    mov r1, r2

你的程序应该工作正常

请注意,在调用
printf
之后,还应清除
r0
,以便
main
返回零,而不是垃圾


您可能会发现它很有用。

argv
是一个数组,作为单个参数而不是一系列参数传递给
main
<因此,C语言中的code>argv[0]在臂组件中转换为
[r1]
argv[1]
[r1,4]
argv[2]
[r1,8]
,等等。每个数组元素的偏移量增加4个字节,因为
argv
是指针数组,这是纯ARM(不是AArch64),所以指针的宽度为32位,即4个字节

如果你改变

    mov r1, r2

你的程序应该工作正常

请注意,在调用
printf
之后,还应清除
r0
,以便
main
返回零,而不是垃圾


您可能会发现这很有帮助。

这里是我目前正在查看的一些反汇编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吗?

这里是我目前正在查看的一些反汇编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吗?

为什么你认为
argv[0]
r1
中而
argv[1]
R2
中?我有95%的把握认为这是错误的。@zwol函数参数在r0、r1等中传递。只传递到某个限制,更重要的是,
argv[0]
argv[1]
等不应作为单独的参数传递。你试过我答案中的东西了吗?@zwol我没有机会,但重新考虑一下,所有argv都应该在r1中,并且可以使用偏移量来逐步通过它。很可能r1是指向指针**argv的指针。或者*argv[]或argv[]但是你看它只是一个指针而不是一个元素,所以它很可能是指向指针数组的指针。为什么你认为
argv[0]
r1
中而
argv[1]
r2
中?我有95%的把握认为这是错误的。@zwol函数参数在r0、r1等中传递。只传递到某个限制,更重要的是,
argv[0]
argv[1]
等不应作为单独的参数传递。你试过我答案中的东西了吗?@zwol我没有机会,但重新考虑一下,所有argv都应该在r1中,并且可以使用偏移量来逐步通过它。很可能r1是指向指针**argv的指针。或者*argv[]或argv[]但是你看它只是一个指针而不是一个元素,所以它很可能是指向一个指针数组的指针。是的,如果你做了一个测试函数并反汇编它,它就是argv[1]所在的位置。r1是指向指针数组的地址r1+0是argv[0],r1+4是argv[1],依此类推。是的,如果您创建一个测试函数并将其反汇编,则argv[1]正好位于该函数所在的位置。r1是指向指针数组的地址r1+0是argv[0],r1+4是argv[1]等等。我不知道你所说的“r1中容纳的参数太多”是什么意思。如果您所在的系统支持
main
的第三个
envp
参数,则该参数将位于R2中,但您只需要一个指针即可指向任意长度的数组。您可能会发现这一点很有帮助。@zwol的第一条评论一针见血。Argv可以具有任意长度。我不知道你所说的“超过R1所能容纳的参数”是什么意思。如果您所在的系统支持
main
的第三个
envp
参数,则该参数将位于R2中,但您只需要一个指针即可指向任意长度的数组。您可能会发现这一点很有帮助。@zwol的第一条评论一针见血。Argv可以具有任意长度。还有一些关于争论。