Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 用户输入和输出不';我不能在我的汇编代码中工作_Macos_Assembly_X86_Nasm_System Calls - Fatal编程技术网

Macos 用户输入和输出不';我不能在我的汇编代码中工作

Macos 用户输入和输出不';我不能在我的汇编代码中工作,macos,assembly,x86,nasm,system-calls,Macos,Assembly,X86,Nasm,System Calls,下面的程序编译时没有错误,但运行时不会提示输入,也不会打印任何内容。有什么问题,我该如何解决 我使用以下命令组合和链接: /usr/local/bin/nasm -f macho32 $1 ld -macosx_version_min 10.9.0 -lSystem -o run $filename.o -e _start -lc 我的代码是: section .data ;New line string NEWLINE: db 0xa, 0xd LENGTH: equ

下面的程序编译时没有错误,但运行时不会提示输入,也不会打印任何内容。有什么问题,我该如何解决

我使用以下命令组合和链接:

/usr/local/bin/nasm -f macho32 $1
ld -macosx_version_min 10.9.0 -lSystem -o run $filename.o -e _start -lc
我的代码是:

section .data
    ;New line string
    NEWLINE: db 0xa, 0xd
    LENGTH: equ $-NEWLINE

section .bss    
INPT: resd 1

section .text   
global _start
_start:


;Read character
mov eax, 0x3
mov ebx, 0x1
mov ecx, INPT
mov edx, 0x1
int 80h

;print character
mov eax, 0x4
mov ebx, 0x1
mov ecx, INPT
mov edx, 0x1
int 80h

;Print new line after the output 
mov eax, 0x4
mov ebx, 0x1
mov ecx, NEWLINE
mov edx, LENGTH
int 0x80

;Terminate
mov eax, 0x1
xor ebx, ebx
int 0x80

代码中有迹象表明,在为OS/X(BSD)生成代码时,您可能正在使用Linux教程。Linux和OS/X有不同的系统调用约定。在OS/X中,32位程序
int0x80
要求在堆栈上传递参数(EAX中的syscall除外)

在OS/X上通过
int 0x80
进行32位系统调用时需要注意的重要事项有:

  • 在堆栈上传递的参数,从右向左推
  • 推送所有参数后,必须在堆栈上再分配4个字节(DWORD)
  • eax寄存器中的系统调用号
  • 通过中断0x80调用
按与
int 0x80相反的顺序在堆栈上推送参数后,必须在堆栈上再分配4个字节(DWORD)。堆栈上内存位置的值并不重要。这个需求是来自一个应用程序的工件

系统调用号及其参数的列表可以在APPLE中找到。您将需要以下系统调用:

我已经对一些示例代码进行了注释,这些代码在功能上与您试图实现的类似:

section .data
    ;New line string
    NEWLINE: db 0xa, 0xd
    LENGTH: equ $-NEWLINE

section .bss
    INPT: resd 1

global _start

section .text
_start:
    and     esp, -16      ; Make sure stack is 16 byte aligned at program start
                          ;     not necessary in this example since we don't call 
                          ;     external functions that conform to the OS/X 32-bit ABI

    push    dword 1       ; Read 1 character
    push    dword INPT    ; Input buffer
    push    dword 0       ; Standard input = FD 0
    mov     eax, 3        ; syscall sys_read
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword 1       ; Print 1 character
    push    dword INPT    ; Output buffer = buffer we read characters into
    push    dword 1       ; Standard output = FD 1
    mov     eax, 4        ; syscall sys_write
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword LENGTH  ; Number of characters to write
    push    dword NEWLINE ; Write the data in the NEWLINE string
    push    dword 1       ; Standard output = FD 1
    mov     eax, 4        ; syscall sys_write
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword 0       ; Return value from program = 0
    mov     eax, 1        ; syscall sys_exit
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
只有在需要将堆栈与16字节边界对齐作为未来堆栈操作的基线时,才需要使用
和esp,-16
。如果您打算调用符合标准的外部函数,则堆栈应在函数调用之前立即对齐16字节。通过
int 0x80
进行的系统调用不需要此对齐

您应该能够将其组装并链接到:

nasm -f macho32 test.asm -o test.o
ld -macosx_version_min 10.9.0 -o test test.o -e _start -lSystem
并使用以下工具运行它:

./test

int 0x80
在OSX上的工作方式不同。
int 0x80
(EAX除外)的参数在堆栈上以32位代码传递,而不是在寄存器中。您编写的代码看起来像是为Linux编写的。我推荐一种新的。Linux和OSX之间的系统调用号也不同。同样,一旦您将代码转换为OS/X,您应该知道标准输入是文件描述符0,标准输出是文件描述符1。您对输入和输出都使用标准输出(1),这会引起问题。@Michael Petch是的,您是对的,谢谢!
./test