繁体   English   中英

用户输入和输出在我的汇编代码中不起作用

[英]User input and output doesn't work in my assembly code

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

我使用这些命令来组装和链接:

/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 具有不同的SYSCALL调用约定。 在 OS/X 32 位程序中int 0x80需要在堆栈上传递参数( EAX 中的系统调用除外)。

在 OS/X 上通过int 0x80使用 32 位SYSCALL需要注意的重要事项是:

  • 在堆栈上传递的参数,从右到左推送
  • 压入所有参数后,您必须在堆栈上分配额外的 4 个字节(一个DWORD
  • eax 寄存器中的系统调用号
  • 通过中断 0x80 调用

在为int 0x80以相反的顺序将参数压入堆栈后,您必须在堆栈上分配额外的 4 个字节(一个DWORD )。 堆栈上该内存位置的值无关紧要。 此要求是旧 UNIX 约定的产物

SYSCALL编号及其参数的列表可以在APPLE 头文件中找到 您将需要这些SYSCALL

 1 AUE_EXIT ALL { void exit(int rval); } 3 AUE_NULL ALL { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); } 4 AUE_NULL ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); }

我已经评论了一些示例代码,这些示例代码的功能与您可能试图实现的功能相似:

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

and esp, -16仅当您需要将堆栈与 16 字节边界对齐作为未来堆栈操作的基线时才需要。 如果您打算调用符合OS/X 32 位 ABI的外部函数,则堆栈应为 16 字节对齐,紧接在函数CALL 之前 通过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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM