如何获取 nasm 中系统调用 getcwd 返回字符串的真实长度?

发布于 2024-12-13 16:00:30 字数 1633 浏览 3 评论 0原文

我的程序调用中断80h的函数183(getcwd),它将当前工作目录的绝对路径名复制到buff指向的内存位置,其长度为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

My program calls function 183 (getcwd) of interrupt 80h which copies an absolute pathname of the current working directory to the memory location pointed to by buff, which is of length 4096. Returned absolute pathname length is usually less than 4096 bytes so i want to get its true length. How can i do that?

%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

I add code to find length of null terminated string to my program as following and it works:

%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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

若能看破又如何 2024-12-20 16:00:31

问:如何查找字符串(例如“getcwd()”返回的字符串)的长度?

答:与标准库函数“strlen()”的做法相同:解析字符串直到找到“\0”分隔符,然后返回该位置作为字符串长度。

附:
我强烈建议您考虑使用 Gnu Assembler“gas”而不是“nasm”。一旦您开始使用 x86 以外的汇编器,“bass-ackwards”Intel 语法就会变得非常烦人。

恕我直言 ...

Q: How do I find the length of a string (e.g. the string returned by "getcwd()")?

A: The same way the standard library function "strlen()" would do it: parse the string until you find a '\0' delimiter, then return that position as the string length.

PS:
I'd strongly urge you to consider using Gnu Assembler "gas" instead of "nasm". As soon as you start playing with assemblers other than x86, the "bass-ackwards" Intel syntax gets really annoying.

IMHO ...

谈场末日恋爱 2024-12-20 16:00:31

我认为您的 strlen 例程(scasb)可以在 ecx = -1 下工作,但在 ecx = 4096 下则不行。尝试一下。

编辑:我没有注意到你减去了 4096。这应该可以。对不起。

我注意到“getcwd”有点“有趣”。它是一个系统调用,但出现在“man 3”中,而不是预期的“man 2”中。不知道为什么。

最好的,
坦率

Your strlen routine (scasb) would work with ecx = -1, but not with ecx = 4096 I think. Try that.

Edit: I didn't notice that you subtracted 4096. That should work. Sorry.

I notice that "getcwd" is kinda "funny". It is a system call, but appears in "man 3", not "man 2" as expected. No idea why.

Best,
Frank

十级心震 2024-12-20 16:00:31

这不是对你的问题的回答;这是一个提醒,您不应该自己进行系统调用。即使您坚持使用汇编语言进行编程(为什么?),您也应该让 C 库为您进行系统调用,因为:

  • 它知道如何设置 errno。
  • 它将让您免受您不想了解的低级别 ABI 变化的影响。
  • 它将自动使用最有效的可用陷阱序列,例如在可能的情况下使用sysentersyscall而不是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 所要求的。)

This is not an answer to your question; it is a reminder that you should not make system calls yourself. Even if you insist on programming in assembly (why?) you should let the C library make system calls for you, because:

  • It knows how to set errno.
  • It will insulate you from low-level ABI variations that you don't want to have to know about.
  • It will automatically use the most efficient available trap sequence, such as using sysenter or syscall rather than int when possible.

All the system calls are available as regular old C functions. Here's your program adjusted to do this properly:

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

(The gunk at the top of main ensures 16-byte stack pointer alignment, which is required by the ABI.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文