0

我今天正在做一些编码,并在其他主题的帮助下尝试编写自己的程序。它的想法是将我在开始时输入的值(它是 ascii)更改为正常值。所以,我想在控制台中看到:

  1. 编号 [A-1, .., Z-26] A
  2. 1

我输入 A 时的输出为 1,B 为 2,依此类推。我得到的输出是大量垃圾。

这是我的代码:

SYSCALL = 0X80
SYSEXIT = 1
SYSREAD = 3
SYSWRITE = 4
STDIN = 0
STDOUT = 1  

.data
.align 32

NUMBER_MAXLEN = 2
NUMBER: .space NUMBER_MAXLEN
NUMBER_LEN: .long 0

MSG_NUMBER: .ascii "Number [A-1, .., Z-26] "
MSG_NUMBER_LEN = . - MSG_NUMBER

.text
.global _start

_start:

#show
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $MSG_NUMBER, %ecx
mov $MSG_NUMBER_LEN, %edx
int $SYSCALL

#read
mov $SYSREAD, %eax
mov $STDIN, %ebx   
mov $NUMBER, %ecx
mov $NUMBER_MAXLEN, %edx
int $SYSCALL

#length
sub $1, %eax
mov %eax, NUMBER_LEN

#Change to normal value
xor %eax, %eax
movb NUMBER, %al
sub $'A', %al
add $1, %al
movb %al, NUMBER

#Print
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $NUMBER, %ecx
mov $NUMBER_LEN, %edx
int $SYSCALL     

END:
mov $SYSEXIT, %eax
int $SYSCALL

我做错了什么?怎么能好..修好?

4

2 回答 2

0

系统__nr_write调用 (4) 只是打印字符串,它不充当printf函数。因此,您需要在打印之前将数字转换为其字符串表示形式。

这是一些伪代码,说明了如何做到这一点:

char buffer[10];
char *p = &buffer[9];

*p = 0;  // NULL terminator
do {
  p--;
  *p = (number % 10) + '0';
  number /= 10;
} while (number != 0);

print(buffer);
于 2013-03-24T15:21:21.307 回答
0

如果用户输入“Z”,你要打印“26”吗?您可以使用查找表,或者自己进行一些转换。英特尔/NASM 格式:

%define SYSCALL  0X80
%define SYSEXIT  1
%define SYSREAD  3
%define SYSWRITE  4
%define STDIN  0
%define STDOUT 1  

%define NUMBER_MAXLEN 2
section .data

MSG_NUMBER: db "Number [A-1, .., Z-26] ", 0
MSG_NUMBER_LEN equ $ - MSG_NUMBER

section .bss

NUMBER:         resb NUMBER_MAXLEN
NumToPrint      resb 3
NUMBER_LEN:     resd 1

section .text
global main

main:

;show
    mov     eax, SYSWRITE
    mov     ebx, STDOUT
    mov     ecx, MSG_NUMBER
    mov     edx, MSG_NUMBER_LEN
    int     SYSCALL

;~ #read
    mov     eax, SYSREAD
    mov     ebx, STDIN
    mov     ecx, NUMBER
    mov     edx, NUMBER_MAXLEN
    int     SYSCALL

;~ #length
    sub     eax, 1
    mov     NUMBER_LEN, eax 

;~ #Change to normal value
    movzx   eax,  byte [NUMBER]
    push    eax
    call    IsValidChar
    test    eax, eax
    js      main                            ; not valid input, repeat prompt

    push    NumToPrint
    push    eax
    call    dwtoa                           ; convert to ASCII

;~ #Print
    mov     edx, eax
    mov     eax, SYSWRITE
    mov     ebx, STDOUT
    mov     ecx, NumToPrint        
    int     SYSCALL    

End:
    mov     eax, SYSEXIT
    int     SYSCALL

;~ #########################################    
IsValidChar:
    mov     eax, [esp + 4]

.0to9:
    cmp     eax, "0"
    jb      .NoGood
    cmp     eax, "9"
    ja      .AtoZ
    jmp     .NoGood

.AtoZ:
    cmp     eax, "A"
    jb      .NoGood
    cmp     eax, "Z"
    ja      .atoz
    sub     eax, 64                         ; convert letter index to number equiv.
    jmp     .Done

.atoz:
    cmp     eax, "a"
    jb      .NoGood
    cmp     eax, "z"
    ja      .NoGood
    sub     eax, 96                         ; convert letter index to number equiv.
    jmp     .Done

.NoGood:
    xor     eax, eax
    dec     eax
.Done:
    ret     4

您将需要创建自己的 dwtoa(DWORD 到 ASCII)。

在此处输入图像描述

于 2013-03-24T15:37:41.850 回答