簡體   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