1

I'm using the Raspberry Pi to learn ARM assembly. I'm still beginning but I would like to know how I can read the values of argv.

I figured out that the value of argc is held in register 0 (r0) at the beginning of a program, but I can't figure out where the argv value is stored. I assume it's somewhere in the stack, but I'm not able to find it.

Can someone help with this?


Edit: So the answer I marked as correct allowed me to find the values of argv. To summarize, the value of argc is found in register r0 when the program launches. r1 contains an address to an array of addresses. These addresses point to the relevant values of argv.

6
  • 1
    They/it are on the stack. See an example here. Commented Feb 28, 2017 at 14:41
  • @artlessnoise They/it are on the stack in _start, by the time you reach main they should be in registers already. Commented Feb 28, 2017 at 14:45
  • @DmitryGrigoryev He doesn't have main() as he is coding in assembler! Commented Feb 28, 2017 at 14:47
  • 1
    Also, I think that argc being in R0 is a happy co-incident. It should also be the first value on the stack. It is probably better to use that one as most 'C' library start up code uses this value. I don't have a canonical reference on that. Commented Feb 28, 2017 at 14:52
  • 1
    @DmitryGrigoryev, What is the difference between the _start and main labels in assembly? I don't have a _start label. Maybe it's because I am using gcc as a linker? Commented Mar 1, 2017 at 2:20

1 Answer 1

3

According to ARM ABI, the second primitive argument to a function should be stored in R1. Bear in mind that argv is a char**, i.e. an address pointing to a table of argc pointers. The first pointer in this table points to a NULL-terminated string containing the executable name, and following pointers point to individual arguments, also represented as NULL-terminated strings.

In case I'm mistaken, just build a simple program accessing argv and see where it takes it from:

int main (int argc, char *argv[])
{
  return argv[0][0];
}

Note that while you're using assembler, gcc will still include startup code from standard library in your program, defining the _start symbol for you and making C-style main function the entry point, so the above still applies to you. However, since you're learning assembler, you may be interested in getting rid of standard library completely, which is done with gcc -nostdlib. Note that you will need to provide your own code for _exit() function to be able to terminate your program properly. See this tutorial for a detailed walk-through.

Sign up to request clarification or add additional context in comments.

3 Comments

Err, this is somewhat wrong. It is correct that a 'C' program will get things like this. However, an assembler program has no 'C' machinery so the question is how to get argv to R1. This answer assumes it is there already?
@DmitryGrigoryev, I am not using inline assembler. I am using Assembly and compiling to object code with as and linking with gcc. I am debugging with gdb. In your answer you mention that argv is a pointer to a pointer, this might be where I am making my mistake. I will check that.
@artlessnoise Turns out that linking with gcc includes that C machinery in the output by default. I have fixed my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.