Как я могу получить истинную длину возвращаемой строки syscall getcwd в nasm? - PullRequest
1 голос
/ 06 ноября 2011

Моя программа вызывает функцию 183 (getcwd) прерывания 80h, которое копирует абсолютный путь к текущему рабочему каталогу в область памяти, на которую указывает буфер, длиной 4096. Возвращенная длина абсолютного пути обычно меньше 4096 байтя хочу получить его истинную длину.Как я могу это сделать?

%define LF 0Ah      ; Line feed ASCII code.
%define STDOUT_FILENO 1 ; Standard output stream.
%define SYS_exit    1
%define SYS_write   4
%define SYS_getcwd  183
SECTION .bss
    buff resb 4096
SECTION .text
    global _start
_start:
    mov eax, SYS_getcwd ; getcwd
    mov ebx, buff
    mov ecx, 4096
    int 80h
    mov eax, SYS_write  ; print result to stdout
    mov ebx, STDOUT_FILENO
    mov ecx, buff
    mov edx, 4096
    int 80h
    mov eax, SYS_exit   ; exit
    mov ebx, 0
    int 80h

Я добавляю код, чтобы найти длину строки с нулевым символом в конце для моей программы следующим образом, и она работает:

%define LF 0Ah      ; Line feed ASCII code.
%define STDOUT_FILENO 1 ; Standard output stream.
%define SYS_exit    1
%define SYS_write   4
%define SYS_getcwd  183
SECTION .data
    mesg1 db "Can't not find string length.",LF
    mesg1_l db $-mesg1
SECTION .bss
    buff resb 4096
SECTION .text
    global _start
_start:
    mov eax, SYS_getcwd ; getcwd
    mov ebx, buff
    mov ecx, 4096
    int 80h
    mov al, 0       ; find string length with scasb
    mov edi, buff
    cld
    repne scasb
    jne error1
    sub ecx, 4096
    neg ecx
    mov edx,ecx
print:  mov byte [buff + ecx],LF
    mov byte [buff + ecx + 1], 0
    inc edx
    mov eax, SYS_write  ; print result to stdout
    mov ebx, STDOUT_FILENO
    mov ecx, buff
    int 80h
    jmp exit
error1: mov eax, SYS_write
    mov ebx, STDOUT_FILENO
    mov ecx, error1 
    mov edx, mesg1_l
    int 80h
exit:   mov eax, SYS_exit   ; exit
    mov ebx, 0
    int 80h

Ответы [ 3 ]

3 голосов
/ 06 ноября 2011

В: Как мне найти длину строки (например, строку, возвращаемую функцией "getcwd ()")?

A: Точно так же, как стандартная библиотечная функция "strlen ()" делает это: анализирует строку, пока не найдет разделитель '\ 0', а затем вернет эту позицию как длину строки.

PS: Я настоятельно призываю вас рассмотреть возможность использования Gnu Assembler «газ» вместо «насм». Как только вы начинаете играть с ассемблерами, отличными от x86, синтаксис Intel с «басами» становится действительно раздражающим.

ИМХО ...

0 голосов
/ 24 июля 2012

Ваша процедура strlen (scasb) будет работать с ecx = -1, но не с ecx = 4096, я думаю. Попробуйте это.

Редактировать: я не заметил, что вы вычли 4096. Это должно сработать. К сожалению.

Я заметил, что "getcwd" довольно "забавно". Это системный вызов, но он появляется в «человеке 3», а не в «человеке 2», как ожидалось. Понятия не имею, почему.

Лучший, Frank

0 голосов
/ 06 ноября 2011

Это не ответ на ваш вопрос; это напоминание о том, что вы не должны делать системные вызовы самостоятельно . Даже если вы настаиваете на программировании на ассемблере (почему?), Вы должны позволить библиотеке C делать системные вызовы за вас, потому что:

  • Он знает, как установить errno.
  • Это защитит вас от низкоуровневых вариаций ABI, о которых вы не хотите знать.
  • Он будет автоматически использовать наиболее эффективную доступную последовательность ловушек, например, используя sysenter или syscall вместо int, когда это возможно.

Все системные вызовы доступны как обычные старые функции C. Вот ваша программа настроена, чтобы сделать это правильно:

SECTION .bss
    buff resb 4096
SECTION .text
    global main
main:
    push  ebp
    mov   ebp, esp
    and   esp, 0xfffffff0
    sub   esp, 16

    mov   dword ptr [esp+4], 4096
    mov   dword ptr [esp],   buff
    call  getcwd

    mov   dword ptr [esp+8], 4096
    mov   dword ptr [esp+4], buff
    mov   dword ptr [esp],   1
    call  write

    ; exit by returning from main
    xor   eax, eax
    leave
    ret

(Ганк в верхней части main обеспечивает выравнивание указателя стека в 16 байт, что требуется для ABI.)

...