读取程序集中的整数值

时间:2014-07-08 08:01:50

标签: assembly nasm

我有以下程序从用户那里读取一位数整数:

SYS_READ  equ 3
STDIN     equ 0

section .data
msg       db "  eksi: "
msg_len   equ $ - msg

section .bss
num       resd 1
;----------------------     

read_num:
push eax
push ebx
push ecx
push edx

mov edx, msg_len
mov ecx, msg
mov ebx, STDOUT
mov eax, SYS_WRITE
int 80h

mov edx, 4
mov ecx, num
mov ebx, STDIN
mov eax, SYS_READ
int 80h

sub dword [num], 2608     ; attention here

pop edx
pop ecx
pop ebx
pop eax
ret

gdb中观察变量的值,我发现值为2608 + entered_value。我尝试过减去dword '0'等但没有结果的事情。如果我需要 num 为4个字节,我该如何正确读取整数值?

2 个答案:

答案 0 :(得分:1)

嗨,我对组装很新,并且遇到同样的问题,下面的文件显然不是最好的解决方案,但它对我来说至少对于最多9位数的数字,想法是在sys_read eax保存读取字节数之后因此可以使用此数字来获取数值,例如,如果输入为123,则数值为1 * 10 ^ 2 + 2 * 10 ^ 1 + 3 * 10 ^ 0

section .data
section .text
global _ipow
_ipow:
    ; input:
    ; ecx - exponent ( for some reason becoz of
    ; multiplication edx can't be used )
    ; output:
    ; eax - base ^ exponent
    push ecx ; store ecx value
    push edx ; store edx value ( mul )
    mov eax, 1 ; zero exponent
start:
    cmp ecx, 0 ; exit loop condition
    jz finish ; we are done
    mul dword [base] ; eax = eax * base
    dec ecx ; next power
    jmp start ; cycle
finish:
    pop edx ; restore edx value
    pop ecx ; restore ecx value
    ret                         
global _start
_start:
    nop
    ; read input value
    mov eax, 0x03 ; sys_read
    mov ebx, 0 ; stdin
    mov ecx, buf ; memory block
    mov edx, 10 ; number of bytes
    int 0x80 ; syscall
    ; now eax holds the number of bytes read
    dec eax ; discard new line character
    ; now eax holds the number of digits
    mov ebx, 0 ; result
    mov dword [base], 10 ; base 10 system
    mov edx, ecx ; address
    mov ecx, eax ; number of digits
S:
    cmp ecx, 0 ; exit loop condition
    jz F ; we are done
    dec ecx ; exponent
    call _ipow ;
    push ebx ; store ebx
    push edx ; store edx ( mul )
    movzx ebx, byte [edx] ; ascii
    sub ebx, '0'; numeric
    mul ebx ; eax = eax * ebx
    pop edx ; restore edx
    pop ebx ; restore ebx
    inc edx ; next character
    add ebx, eax ; get the numeric value
    jmp S ; cycle
F:
    ; at this point ebx holds the numeric value
    mov eax, 0x1 ; sys_exit
    mov ebx, 0x0 ; error code
    int 0x80 ; syscall
section .bss
    buf resb 10 ; 9 digits + '\n'
    base resd 1 ; numeric system

文件使用

编译
nasm -f elf -g -F dwarf atoi.asm
ld -m elf_i386 atoi.o -o atoi

但可能最好找一些其他解决方案如何正确编写atoi函数

答案 1 :(得分:0)

您只需要用户返回一个数字,因此您应该忽略缓冲区中的其他所有内容。使用示例中给出的缓冲区,您可以执行以下操作:

and dword[num],0FFh
sub dword[num],30h

num后将包含用户输入的数值。如果用户输入了字符,控制代码或任何非数字num将高于9;您的进一步错误处理应考虑到这一点。