使用 INT 21h (DOS) & 读取数字8086组装

发布于 2024-12-11 14:50:56 字数 410 浏览 0 评论 0原文

我需要提示用户一条消息,告诉他写一个数字,然后我存储这个数字并对其进行一些操作 在 INT 21h 中搜索后,我发现了这一点:

INT 21h / AH=1 - read character from standard input, with echo, result is stored in AL.
if there is no character in the keyboard buffer, the function waits until any key is pressed. 

example:

    mov ah, 1
    int 21h

主要问题是这只读取一个字符并将其表示为 ASCII 所以如果我需要写数字“357” 我会把它读成3、5、7

,但这不是我的目标。 有什么想法吗?

I need to prompt to user a msg that tells him to write a number , then I store this number and do some operation on it
After searching in INT 21h I found this :

INT 21h / AH=1 - read character from standard input, with echo, result is stored in AL.
if there is no character in the keyboard buffer, the function waits until any key is pressed. 

example:

    mov ah, 1
    int 21h

The main problem that this only reads one character and represent it as ASCII
so If I need to write the number "357"
I will read it as 3 , 5 , 7

and this is not my goal .
any ideas ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瀞厅☆埖开 2024-12-18 14:50:56

当您成功获取用户输入时,将其指针放入 ESI (ESI = 字符串的地址)

.DATA
myNumber BYTE "12345",0        ;for test purpose I declare a string '12345'

Main Proc
    xor ebx,ebx                ;EBX = 0
    mov  esi,offset myNumber   ;ESI points to '12345'

loopme:

    lodsb                      ;load the first byte pointed by ESI in al

    cmp al,'0'                 ;check if it's an ascii number [0-9]
    jb noascii                 ;not ascii, exit
    cmp al,'9'                 ;check the if it's an ascii number [0-9]
    ja noascii                 ;not ascii, exit

    sub al,30h                 ;ascii '0' = 30h, ascii '1' = 31h ...etc.
    cbw                        ;byte to word
    cwd                        ;word to dword
    push eax
    mov eax,ebx                ;EBX will contain '12345' in hexadecimal
    mov ecx,10
    mul ecx                    ;AX=AX*10
    mov ebx,eax
    pop eax
    add ebx,eax
    jmp loopme                 ;continue until ESI points to a non-ascii [0-9] character
    noascii:
    ret                        ;EBX = 0x00003039 = 12345
Main EndP

When you managed to get the user input, put the its pointer in ESI (ESI = address to the string)

.DATA
myNumber BYTE "12345",0        ;for test purpose I declare a string '12345'

Main Proc
    xor ebx,ebx                ;EBX = 0
    mov  esi,offset myNumber   ;ESI points to '12345'

loopme:

    lodsb                      ;load the first byte pointed by ESI in al

    cmp al,'0'                 ;check if it's an ascii number [0-9]
    jb noascii                 ;not ascii, exit
    cmp al,'9'                 ;check the if it's an ascii number [0-9]
    ja noascii                 ;not ascii, exit

    sub al,30h                 ;ascii '0' = 30h, ascii '1' = 31h ...etc.
    cbw                        ;byte to word
    cwd                        ;word to dword
    push eax
    mov eax,ebx                ;EBX will contain '12345' in hexadecimal
    mov ecx,10
    mul ecx                    ;AX=AX*10
    mov ebx,eax
    pop eax
    add ebx,eax
    jmp loopme                 ;continue until ESI points to a non-ascii [0-9] character
    noascii:
    ret                        ;EBX = 0x00003039 = 12345
Main EndP
懒的傷心 2024-12-18 14:50:56

获得字符串后,您必须将其转换为数字。问题是,您必须编写自己的过程才能做到这一点。这是我通常使用的(虽然是用 C 编写的):

int strToNum(char *s) {
    int len = strlen(s), res = 0, mul = 0;
    char *ptr = s + len;

    while(ptr >= s)
        res += (*ptr-- - '0') * (int)pow(10.0, mul++);

    return res;
}

这是解释。首先,*ptr-- - '0'获取数字的整数表示形式(这样'9' - '0' = 9,然后它递减< code>ptr 以便它指向前一个字符。一旦我们知道该数字,我们就必须将其提高到 10 的幂。例如,假设输入是“357”,代码的作用是:

('7' - '0' = 7) * 10 ^ 0 =   7 +
('5' - '0' = 5) * 10 ^ 1 =  50 +
('3' - '0' = 3) * 10 ^ 2 = 300 = 
---------------------------------
                           357

Once you've got the string you have to convert it to number. The problem is, you have to code your own procedure to do that. This is the one I usually use (written in C though):

int strToNum(char *s) {
    int len = strlen(s), res = 0, mul = 0;
    char *ptr = s + len;

    while(ptr >= s)
        res += (*ptr-- - '0') * (int)pow(10.0, mul++);

    return res;
}

Here's the explanation. First of all, *ptr-- - '0' gets the integer representation of a number (so that '9' - '0' = 9, then it decremenst ptr so that it points to the previous char. Once we know that number, we have to raise it to a power of 10. For example, suppose the input is '357', what the code does is:

('7' - '0' = 7) * 10 ^ 0 =   7 +
('5' - '0' = 5) * 10 ^ 1 =  50 +
('3' - '0' = 3) * 10 ^ 2 = 300 = 
---------------------------------
                           357
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文