我正在分割故障 - 组装

发布于 2025-01-23 21:26:45 字数 1771 浏览 0 评论 0原文

我正在尝试汇编X86,但我得到了ZSH:分割故障./test错误。 我正在尝试自己制作一些基本图书馆,以便以后使用。它分为三个文件 - string.asm用于字符串操作,stdio.asm用于标准IO操作以及libtest.asm用于库测试。我打算添加更多功能,但我想先测试这些功能。

;;;;;;;;;;;;;;;;;
;;; stdio.asm ;;;
;;;;;;;;;;;;;;;;;
global print ; void print(string* text)
extern strlen ; int32 strlen(string* string)

section .data
stdin dd 0
stdout dd 1
stderr dd 2
newline db 0x0a, 0x00

section .text

print:
    push ebp
    mov ebp, esp
    push eax
    push ebx
    push ecx
    push edx
    
    ; get parameters
    mov ecx, dword [ebp+8]
    ; call strlen
    push ecx
    call strlen
    add esp, 4
    ; moving length
    mov ecx, eax
    ; moving syscall num and out desc
    mov eax, 4
    mov ebx, [stdout]
    ; syscall
    int 0x80
    
    pop edx
    pop ecx
    pop ebx
    pop eax
    mov esp, ebp
    pop ebp
    ret

;;;;;;;;;;;;;;;;;
;; string.asm ;;;
;;;;;;;;;;;;;;;;;
global strlen ; int32 strlen(string* str)

section .text
strlen:
    push ebp
    mov ebp, esp
    push ebx
    
    mov ebx, dword [ebp+8]
    
    mov eax, 0
    loop1:
        cmp [ebx+eax], byte 0x00
        inc eax
        jne loop1
    dec eax
    
    pop ebx
    mov esp, ebp
    pop ebp
    ret

;;;;;;;;;;;;;;;;;
;; libtest.asm ;;
;;;;;;;;;;;;;;;;;
global _start

extern print

section .data
msg db 'Hello, world!', 0x0a, 0x00

section .text
_start:
    push msg
    call print
    add esp, 4
    
    mov eax, 1
    mov ebx, 0
    int 0x80

执行:

$ nasm -f elf32 stdio.asm

$ nasm -f elf32 string.asm </

code $ nasm -f elf32 libtest.asm

$ ld -m elf_i386 -o test stdio.o string.o libtest.o

$ ./ test

我不知道该错误可能在哪里你们。

谢谢!

I'm trying assembly x86 but I got the zsh: segmentation fault ./test error.
I am trying to make some basic library myself to use later on. It's divided into three files - string.asm for string manipulation, stdio.asm for standard io operations, and libtest.asm for library testing. I was planning to add more functions, but I wanted to test these first.

;;;;;;;;;;;;;;;;;
;;; stdio.asm ;;;
;;;;;;;;;;;;;;;;;
global print ; void print(string* text)
extern strlen ; int32 strlen(string* string)

section .data
stdin dd 0
stdout dd 1
stderr dd 2
newline db 0x0a, 0x00

section .text

print:
    push ebp
    mov ebp, esp
    push eax
    push ebx
    push ecx
    push edx
    
    ; get parameters
    mov ecx, dword [ebp+8]
    ; call strlen
    push ecx
    call strlen
    add esp, 4
    ; moving length
    mov ecx, eax
    ; moving syscall num and out desc
    mov eax, 4
    mov ebx, [stdout]
    ; syscall
    int 0x80
    
    pop edx
    pop ecx
    pop ebx
    pop eax
    mov esp, ebp
    pop ebp
    ret

;;;;;;;;;;;;;;;;;
;; string.asm ;;;
;;;;;;;;;;;;;;;;;
global strlen ; int32 strlen(string* str)

section .text
strlen:
    push ebp
    mov ebp, esp
    push ebx
    
    mov ebx, dword [ebp+8]
    
    mov eax, 0
    loop1:
        cmp [ebx+eax], byte 0x00
        inc eax
        jne loop1
    dec eax
    
    pop ebx
    mov esp, ebp
    pop ebp
    ret

;;;;;;;;;;;;;;;;;
;; libtest.asm ;;
;;;;;;;;;;;;;;;;;
global _start

extern print

section .data
msg db 'Hello, world!', 0x0a, 0x00

section .text
_start:
    push msg
    call print
    add esp, 4
    
    mov eax, 1
    mov ebx, 0
    int 0x80

Execution:

$ nasm -f elf32 stdio.asm

$ nasm -f elf32 string.asm

$ nasm -f elf32 libtest.asm

$ ld -m elf_i386 -o test stdio.o string.o libtest.o

$ ./test

I don't know where the error could be, so I would appreciate any help from you guys.

Thanks!

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

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

发布评论

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

评论(1

握住我的手 2025-01-30 21:26:45

两个错误:

    ; moving length
    mov ecx, eax
    ; moving syscall num and out desc
    mov eax, 4
    mov ebx, [stdout]
    ; syscall
    int 0x80

参考系统调用需要ecx的缓冲指针,而edx中的长度则需要。您的长度在ecx中,缓冲指针根本没有。进行:

    mov edx, eax
    mov ecx, dword [ebp+8]
    mov eax, 4
    mov ebx, [stdout]
    int 0x80

接下来,查看:

        cmp [ebx+eax], byte 0x00
        inc eax
        jne loop1

inc指令根据其输出设置零标志。因此,您的jne不在cmp的结果上分支,而是在是否将eax递增为零上(即包裹)。因此,您的循环会迭代太多次。

jne需要立即在cmp之后,没有其他标志模拟说明。您可以通过几种方法来重写。一个是:

    mov eax, -1
loop1:
        inc eax
        cmp byte [ebx+eax], 0x00
        jne loop1

请注意,最后消除了对额外的dec eax的需求。

修复这些内容后,该程序对我有用。

Two bugs:

    ; moving length
    mov ecx, eax
    ; moving syscall num and out desc
    mov eax, 4
    mov ebx, [stdout]
    ; syscall
    int 0x80

Referring to Linux system call conventions, the write system call needs the buffer pointer in ecx and the length in edx. You have the length in ecx and the buffer pointer is nowhere at all. Make it:

    mov edx, eax
    mov ecx, dword [ebp+8]
    mov eax, 4
    mov ebx, [stdout]
    int 0x80

Next, look at:

        cmp [ebx+eax], byte 0x00
        inc eax
        jne loop1

The inc instruction sets the zero flag according to its output. So your jne doesn't branch on the result of the cmp, but rather on whether eax was incremented to zero (i.e. wrapped around). So your loop will iterate far too many times.

The jne needs to be immediately after the cmp, with no other flag-modifying instructions in between. There are several ways you could rewrite. One would be:

    mov eax, -1
loop1:
        inc eax
        cmp byte [ebx+eax], 0x00
        jne loop1

Note this eliminates the need for the extra dec eax at the end.

After fixing these, the program works for me.

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