Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm для Linux/Unix > Прочитать аргумент коммандной строки


Автор: Shaggie 14.8.2007, 13:20
Допустим написал я свою программу и запускаю её из консоли:

./myprogram arg1 arg2

Как мне из-под линукса в ассемблере прочитать эти аргументы с помощью системного вызова write? В винде легко выкручиваюсь вызовом GetCommandLine, в сях читаю argv[], а вот в ассемблере застрял...

Интересен именно системный write, но и другие варианты (если есть) будут приняты с большим интересом.

Автор: Shaggie 15.8.2007, 14:04
Ёлки-палки, только сейчас дошло... не write, а read! Вот это я выдал... И ведь хоть бы кто поправил!

Неужели нет здесь программистов, которым доводилось получать аргументы в линуксе с помощью системных вызовов???

Автор: MAKCim 15.8.2007, 16:50
Код

.data
.asciz "%s\n"
.text
.globl main
main:
    pushl    %ebp
    movl    %esp, %ebp
    cmpl    $1, 8(%ebp)    /* получаю значение argc и сравниваю с единицей */
    jle    2f
    movl    12(%ebp), %eax    /* получаю значение argv */
1:
    movl    (%eax), %edx
    testl    %edx, %edx
    jz    2f
    pushl    %eax
    pushl    %edx
    pushl   $.data
    call    printf
    addl    $8, %esp
    popl    %eax
    addl    $4, %eax
    jmp    1b
2:
    leave
    xorl    %eax, %eax
    ret

Автор: Shaggie 20.8.2007, 08:12
MAKCim, спасибо что заставил подумать головой!

Итак, на момент запуска программы в esp находится число равное n аргументов, переданных программе, а в esp+(4*n) - указатель на n-ый аргумент. То есть нет нужды использовать системные вызовы.

Минус один - строка, к примеру, "1234567" хранится в памяти в виде "34333231 00373635", то есть прочитать её с помощью scas не получится, надо писать собственный алгоритм разбора строки. По крайней мере, с ходу я готовых процессорных инструкций для такой ситуации не нашёл...

Но это уже совсем другая история. Большое спасибо, тема закрыта.

Автор: MAKCim 20.8.2007, 09:16
Цитата(Shaggie @  20.8.2007,  08:12 Найти цитируемый пост)
Итак, на момент запуска программы в esp находится число равное n аргументов, переданных программе, а в esp+(4*n) - указатель на n-ый аргумент. То есть нет нужды использовать системные вызовы.

нет
в стеке последовательно лежат
ESP: argc
ESP + 4: argv (указатель на аргументы)
ESP + 8: env (указатель на переменные среды)
когда мы делаем
Код

movl    12(%ebp), %eax

мы получаем в EAX адрес первого элемента массива из адресов строк аргументов, переданных в программу
Цитата(Shaggie @  20.8.2007,  08:12 Найти цитируемый пост)
Минус один - строка, к примеру, "1234567" хранится в памяти в виде "34333231 00373635"

опять нет
ты не путай с числом (младший байт по младшему адресу)
"1234567" храниться как 31h 32h 33h 34h 35h 36h 37h

Автор: Shaggie 21.8.2007, 10:44
Цитата(MAKCim @  20.8.2007,  10:16 Найти цитируемый пост)
в стеке последовательно лежат
ESP: argc
ESP + 4: argv (указатель на аргументы)
ESP + 8: env (указатель на переменные среды)

хм-м. У меня было всего около пяти минут, чтобы покопаться в линуксе, так что ничего толком не успел... щас объясню.
Есть программа на ассемблере, совсем простенькая, ничего почти не делает. Единственное что важно - она назывется abcde.
Смотрю в отладчике вот так:

gdb -q --args abcde 12345 67890
tb _start
x/x $esp - показывает 0x00000003.
Это я так понимаю три аргумента, первый - название программы, второй и третий - мои строки.

x/x $esp+4 - 0xbffff8a8
x/x $esp+8 - 0xbffff8c8
x/x $esp+12 - 0xbffff8ce
x/x $esp+16 - 0x00000000
То есть esp+4esp+8 и esp+12 содержат указатели на... ща посмотрим...

x/x 0xbffff8a8 - 0x6e69772f - странно! Должно быть имя программы... или я ошибаюсь?
x/x 0xbffff8c8 - 0x34333231 - ага, это второй аргумент
x/x 0xbffff8ce - 0x39383736 - а вот и третий!
Или это gdb так аргументы разбрасывает самовольно?

Цитата(MAKCim @  20.8.2007,  10:16 Найти цитируемый пост)
ты не путай с числом (младший байт по младшему адресу)
"1234567" храниться как 31h 32h 33h 34h 35h 36h 37h 

Бес попутал. Внимательно посмотрел, этот момент прояснился.
x/b 0xbffff8c8 - 0x31
Так что я действительно ошибся и других людей в заблужденье ввёл почём зря.

Тема открывается обратно.

Автор: MAKCim 21.8.2007, 11:35
Цитата(Shaggie @  21.8.2007,  10:44 Найти цитируемый пост)
x/x $esp - показывает 0x00000003.

по ESP должен быть адрес возврата

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)