[英]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.