用户输入和输出并不在我的组装code工作 [英] User input and output doesn't work in my assembly code

查看:140
本文介绍了用户输入和输出并不在我的组装code工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的程序编译没有错误,但运行时不会提示任何输入和任何打印。有什么问题,我怎么能解决这个问题?

我使用这些命令汇编和链接:

 的/ usr / local / bin目录/ NASM -f macho32 $ 1
LD -macosx_version_min 10.9.0 -lSystem -o运行$ filename.o -e _start -lc

我的code是:

 部分。数据
    ;新行字符串
    NEWLINE:DB为0xA,0xd中
    长度:EQU $ -NEWLINE.bss段
INPT:RESD 1.text段
全球_start
_开始:
;读取字符
MOV EAX,0x3中
MOV EBX,为0x1
MOV ECX,INPT
MOV EDX,为0x1
INT 80H;打印字符
MOV EAX,为0x4
MOV EBX,为0x1
MOV ECX,INPT
MOV EDX,为0x1
INT 80H;输出后打印新行
MOV EAX,为0x4
MOV EBX,为0x1
MOV ECX,NEWLINE
MOV EDX,长度
INT 0x80的;终止
MOV EAX,为0x1
XOR EBX,EBX
INT 0x80的


解决方案

有在code迹象表明,你可能会为OS / X(BSD)生产code时,已经使用的是Linux教程。 Linux和OS / X具有不同的 SYSCALL 的调用约定。在OS / X 32位程序 INT 0x80的需要参数(除了系统调用中的 EAX 的)在堆栈上传递。

重要的事情要通过 0x80的INT 在OS / X是意识到与32位的 SYSCALL 取值


  

      
  • 在栈上传递的参数,推从右至左

  •   
  • 您必须分配在堆栈上额外的4个字节( DWORD 的),你把所有的参数之后

  •   
  • 在EAX寄存器系统调用号

  •   
  • 将0x80中断
  • 通话
      

以相反的顺序推栈上的参数为 INT 0x80的您必须在栈上分配额外的4个字节( DWORD 的)后。在堆栈上存储单元中的值无关紧要。此要求从旧的UNIX约定。

SYSCALL 的数量和它们的参数可以在苹果的的头文件。你需要这些的 SYSCALL 取值:


  1 AUE_EXIT ALL {无效出口(INT RVAL); }
3 AUE_NULL ALL {user_ssize_t阅读(INT FD,user_addr_t CBUF,user_size_t nbyte); }
4 AUE_NULL ALL {user_ssize_t写(INT FD,user_addr_t CBUF,user_size_t nbyte); }


我评论过一些例如code,这将是在功能上你可能一直在试图达到什么相似的:

 部分。数据
    ;新行字符串
    NEWLINE:DB为0xA,0xd中
    长度:EQU $ -NEWLINE.bss段
    INPT:RESD 1全球_start.text段
_开始:
    和ESP,-16;在程序启动确保栈16字节对齐
                          ;在本例中没有必要,因为我们不叫
                          ;符合的OS / X的32位ABI外部函数    推DWORD 1;阅读1个字符
    推DWORD INPT;输入缓冲区
    推DWORD 0;标准输入= 0 FD
    MOV EAX,3;系统调用SYS_READ
    子ESP,4;额外的4个堆栈由INT 0x80的需要
    INT 0x80的
    ADD ESP,16;恢复堆栈    推DWORD 1;打印1个字符
    推DWORD INPT;输出缓冲区=缓冲区我们读入字符
    推DWORD 1;标准输出= 1 FD
    MOV EAX,4;系统调用SYS_WRITE
    子ESP,4;额外的4个堆栈由INT 0x80的需要
    INT 0x80的
    ADD ESP,16;恢复堆栈    推DWORD的长度;字符数写
    推DWORD NEWLINE;写在NEWLINE字符串数据
    推DWORD 1;标准输出= 1 FD
    MOV EAX,4;系统调用SYS_WRITE
    子ESP,4;额外的4个堆栈由INT 0x80的需要
    INT 0x80的
    ADD ESP,16;恢复堆栈    推DWORD 0;从程序返回值= 0
    MOV EAX,1;系统调用sys_exit
    子ESP,4;额外的4个堆栈由INT 0x80的需要
    INT 0x80的

和ESP,-16 是只需要如果你需要堆栈对齐到16字节边界作为未来堆栈操作的基准。如果您打算调用符合<一个外部函数href=\"https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4\"相对=nofollow> OS / X 32位ABI 的堆栈预计将对齐16字节立即preceding功能的呼叫的。这种一致性通过 0x80的INT 是没有必要的系统调用。

您应该能够组装和链接它:

  NASM -f macho32 TEST.ASM -o test.o
LD -macosx_version_min 10.9.0测试-o -e test.o _start -lSystem

和与运行:

  ./测试

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). Linux and OS/X have differing SYSCALL calling conventions. In OS/X 32-bit programs int 0x80 requires parameters (except the syscall in EAX) to be passed on a stack.

The important things to be aware of with 32-bit SYSCALLs via int 0x80 on OS/X are:

  • 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
  • syscall number in the eax register
  • call by interrupt 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. The value in that memory location on the stack doesn't matter. This requirement is an artifact from an old UNIX convention.

A list of the SYSCALL numbers and their parameters can be found in the APPLE header files. You'll need these SYSCALLs:

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. 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. This alignment is not necessary for system calls via 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

这篇关于用户输入和输出并不在我的组装code工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆