[英]User input and output doesn't work in my assembly code
The following program compiles without errors, but when run it doesn't prompt for any input and nothing prints.下面的程序编译没有错误,但运行时它不提示任何输入,也不打印任何内容。 What's the problem, and how can I fix it?
有什么问题,我该如何解决?
I use these commands to assemble and link:我使用这些命令来组装和链接:
/usr/local/bin/nasm -f macho32 $1
ld -macosx_version_min 10.9.0 -lSystem -o run $filename.o -e _start -lc
My code is:我的代码是:
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
There are signs in your code that you may have been using a Linux tutorial when producing code for OS/X(BSD).您的代码中有迹象表明您在为 OS/X(BSD) 生成代码时可能一直在使用 Linux 教程。 Linux and OS/X have differing SYSCALL calling conventions.
Linux 和 OS/X 具有不同的SYSCALL调用约定。 In OS/X 32-bit programs
int 0x80
requires parameters (except the syscall in EAX ) to be passed on a stack.在 OS/X 32 位程序中
int 0x80
需要在堆栈上传递参数( EAX 中的系统调用除外)。
The important things to be aware of with 32-bit SYSCALL s via int 0x80
on OS/X are:在 OS/X 上通过
int 0x80
使用 32 位SYSCALL需要注意的重要事项是:
- arguments passed on the stack, pushed right-to-left
在堆栈上传递的参数,从右到左推送
- you must allocate an additional 4 bytes (a DWORD ) on the stack after you push all the arguments
压入所有参数后,您必须在堆栈上分配额外的 4 个字节(一个DWORD )
- syscall number in the eax register
eax 寄存器中的系统调用号
- call by interrupt 0x80
通过中断 0x80 调用
After pushing arguments on the stack in reverse order for int 0x80
you must allocate an additional 4 bytes (a DWORD ) on the stack.在为
int 0x80
以相反的顺序将参数压入堆栈后,您必须在堆栈上分配额外的 4 个字节(一个DWORD )。 The value in that memory location on the stack doesn't matter.堆栈上该内存位置的值无关紧要。 This requirement is an artifact from an old UNIX convention .
此要求是旧 UNIX 约定的产物。
A list of the SYSCALL numbers and their parameters can be found in the APPLE header files . SYSCALL编号及其参数的列表可以在APPLE 头文件中找到。 You'll need these SYSCALL s:
您将需要这些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); }
I have commented some example code that would be similar in functionality to what you may have been attempting to achieve:我已经评论了一些示例代码,这些示例代码的功能与您可能试图实现的功能相似:
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
The and esp, -16
is only necessary if you need to align the stack to a 16-byte boundary as a baseline for future stack operations. and esp, -16
仅当您需要将堆栈与 16 字节边界对齐作为未来堆栈操作的基线时才需要。 If you intend to call external functions that conform to the OS/X 32-bit ABI the stack is expected to be 16-byte aligned immediately preceding a function CALL .如果您打算调用符合OS/X 32 位 ABI的外部函数,则堆栈应为 16 字节对齐,紧接在函数CALL 之前。 This alignment is not necessary for system calls via
int 0x80
.通过
int 0x80
系统调用不需要这种对齐方式。
You should be able to assemble and link it with:您应该能够组装并链接它:
nasm -f macho32 test.asm -o test.o
ld -macosx_version_min 10.9.0 -o test test.o -e _start -lSystem
And run it with:并运行它:
./test
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.