linux - 如何在 Linux 程序集中读取和显示一个值?

标签 linux assembly x86

我是 Linux 汇编程序的初学者,我有一些问题。我想从键盘读取一些字符,将其转换为值(我知道这种转换应该是从 ASCII 到十进制,对吗?),做一些数学运算(加、减、乘,等等)并在终端中显示结果.我该怎么做?我写了一些代码,但它可能没有意义:

SYSEXIT = 1
EXIT_SUCC = 0
SYSWRITE = 4
SYSCALL = 0x80
SYSREAD = 3

.data
value: .space 5, 0
value_len: .long .-value

result: .long
result_len: .long .-result

.text
.global _start

_start:


movl $SYSREAD, %eax
movl $EXIT_SUCC, %ebx
movl $value, %ecx
movl value_len, %edx
int $SYSCALL

movl $0, %edx
movl value_len, %ecx

for:                            
    movb value(, %edx, 1), %al
    subb $48, %al
    movb %al, result(, %edx, 1)
    inc %edx    
loop for    

add $10, result

movl $0, %edx
movl result_len, %ecx

for1:                           
    movb result(, %edx, 1), %al
    add $48, %al
    movb %al, result(, %edx, 1)
    inc %edx    
loop for1

movl $SYSWRITE, %eax            
movl $SYSEXIT, %ebx 
movl $result, %ecx
movl result_len, %edx
int $SYSCALL

movl $SYSEXIT, %eax
movl $EXIT_SUCC, %ebx
int $SYSCALL

不知道要不要按空格预留内存?或者循环读取字符? 如何转换它,能够进行一些数学运算然后转换它能够显示它? 我知道要获得 ASCII 字符的值,我应该减去 48,但是接下来呢? 我有一个想法,将每个位乘以 2^k,其中 k 是 0,1,2...n 这是个好主意吗?如果是这样,如何实现这样的事情?

如您所见,我有很多问题,但我只需要有人告诉我该怎么做,以及我在问什么。我看到了一些类似的问题,但在 Linux 中没有这样的问题。

提前感谢您提供所有信息。 一切顺利。

最佳答案

首先,在 Linux 中读取和写入控制台是通过使用具有特殊控制台句柄的文件函数,这些句柄始终具有相同的值:STDIN=0、STDOUT=1 和 STDERR=2。

其次,您将需要一些关于 Linux 系统调用的不错的文档。请注意,以 C 为中心的语言(如“man”)并不合适,因为 C 语言不直接使用系统调用,而是具有经常更改参数和结果值的包装器。

在以下站点上,您可以下载 assembly-centric SDK对于 Linux,它包含所需的文档和许多示例以及包含文件。

如果您只需要帮助文件,可以在线浏览:Here

如果问题是从 ASCII 字符串到数字然后再转换回字符串,如果要求不是那么大,这里有两个简单的程序可以完成这项工作。 StrToNum 没有那么高级,它只是简单地转换十进制无符号数:

    ; Arguments:
    ;   esi - pointer to the string
    ; Return:
    ;   CF=0
    ;   eax - converted number
    ;   edx - offset to the byte where convertion ended.
    ;
    ;   CF=1 - the string contains invalid number.
    ;
    StrToNum:
            push    ebx esi edi
            xor     ebx,ebx         ; ebx will store our number

            xor     eax,eax
            mov     al,[esi]
            cmp     al,'0'
            jb      .error
            cmp     al,'9'
            jbe     .digit
            jmp     .error
         .digit:
            sub     al,'0'
            add     ebx,eax
            inc     esi
            mov     al,[esi]
            cmp     al,'0'
            jb      .finish
            cmp     al,'9'
            ja      .finish
            mov     edx,ebx         ; multiply ebx by 10
            shl     ebx,3
            add     ebx,edx
            add     ebx,edx
            jmp     .digit
         .finish:

            mov     eax, ebx
            mov     edx, esi
            clc
            pop     edi esi ebx
            ret

         .error:
            stc
            pop     edi esi ebx
            ret

NumToStr 非常灵活。它将数字转换为任何基数和带符号的字符串:

    ;**********************************************************************************
    ; NumToStr converts the number in eax to the string in any radix approx. [2..26]
    ; Arguments:
    ;   edi - pointer to the string buffer
    ;   ecx - radix
    ;   eax - number to convert.
    ; There is no parameter check, so be careful.
    ; returns: edi points to the end of a converted number
    ;**********************************************************************************
    NumToStr:
        test  eax,eax
        jns   NumToStrU
        neg   eax
        mov   byte [edi],"-"
        inc   edi

    NumToStrU:
        cmp   eax,ecx
        jb    .lessA
        xor   edx,edx
        div   ecx
        push  edx
        call  NumToStrU
        pop   eax

    .lessA:
        cmp   al, 10
        sbb   al, 69h
        das
        stosb
        ret

关于linux - 如何在 Linux 程序集中读取和显示一个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22570524/

相关文章:

linux - Linux 和 Solaris 之间的 RPC 调用

c - 如何告诉 GCC 为实模式生成 16 位代码

c++ - C/C++ 转换为程序集,低级内存行为 : how is it done?

linux - 这个 x86 Hello World using 32-bit int 0x80 Linux system calls from _start 的解释是什么?

linux - _start 中 RET 上的 Nasm 段错误

linux - 用于在 Bash 中检查二进制传输的 ASCII 空间的正则表达式

php - 在 linux 中使用 cURL 上传 http 文件(命令行)

Linux - 使用 SSH 的关闭脚本

assembly - 如何在 ti 汇编中显示 ti 83+/ti 84/ti 84+ 的 a 寄存器的值

linux - 我如何处理 Assembly(IA32) 中的幂函数和平方根函数?