如何在Linux程序集中读取和显示值?

时间:2014-03-21 22:18:21

标签: 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 char的值我应该减去48,但下一步是什么? 我有一个想法将每个位乘以2 ^ k,其中k是0,1,2 ... n这是个好主意?如果是这样,如何实现这样的事情?

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

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

1 个答案:

答案 0 :(得分:0)

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

第二,你需要一些关于Linux系统调用的体面文档。请注意,以C为中心的(如“man”)不合适,因为C语言不直接使用系统调用,但是包装器通常会更改参数和结果值。

在以下网站上,您可以下载适用于Linux的assembly-centric SDK,其中包含所需的文档以及许多示例和包含文件。

如果您只需要帮助文件,可以在线浏览: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