Assembly 汇编程序加载的字符串到十进制表示法

Assembly 汇编程序加载的字符串到十进制表示法,assembly,x86,Assembly,X86,我需要编写一个程序,将加载的字符串更改为十进制符号,并在控制台上写入我们接收到的内容,现在在这段代码中只有echo工作,如何在内存中移动以更改我们接收到的字符串 .align 32 SYSEXIT = 1 SYSREAD = 3 SYSWRITE = 4 STDOUT = 1 STDIN =0 EXIT_SUCCESS = 0 .data bufor: .space 1000 bufor_len = 10 num: .int =10 numm: .int =

我需要编写一个程序,将加载的字符串更改为十进制符号,并在控制台上写入我们接收到的内容,现在在这段代码中只有echo工作,如何在内存中移动以更改我们接收到的字符串

.align 32

SYSEXIT = 1
SYSREAD = 3
SYSWRITE = 4
STDOUT = 1
STDIN =0
EXIT_SUCCESS = 0

.data

    bufor: .space 1000
    bufor_len = 10
    num: .int =10
    numm: .int =1


.text

    text: .ascii "Podaj ciag znakow"
    text_len = . - text

.global _start
_start:

    mov $SYSWRITE, %eax
    mov $STDOUT, %ebx
    mov $text, %ecx
    mov $text_len, %edx
    int $0x80

    mov $SYSREAD, %eax
    mov $STDIN, %ebx
    mov $bufor, %ecx
    mov $bufor_len, %edx
    int $0x80


ety_1:
    mov $bufor, %eax
    mov $al, %ecx
    imul $num, %ecx
ety_2:

    shr $numm, %eax
    mov $al, %ebx
    imul $num, %ebx
    add %ebx, %eax
    cmp %al,lf
    jne ety_2

    int $0x80

    mov $SYSWRITE, %eax
    mov $STDOUT, %ebx
    mov $bufor, %ecx
    mov $bufor_len, %edx
    int $0x80

    mov $SYSEXIT, %eax
    mov $EXIT_SUCCESS, %ebx
    int $0x80

您的字符已经是ASCII格式。您所寻找的只是一种以不同方式输出它们的方法

一般来说,要打印数字的数字表示形式,您需要提取各个数字,对于十进制表示形式,可以通过重复除以10并检查余数,然后将“0”的ASCII代码添加到这些数字中,以获得可打印字符。然后输出可打印的字符

在nasm格式的x86_64汇编中,利用可打印ASCII字符可以用不少于两个、不超过三个十进制数字表示的事实,这里是一种相当粗糙的方法:

global _start

STDIN           equ     0
STDOUT          equ     1
STDERR          equ     2

SYSCALL_READ    equ     0
SYSCALL_WRITE   equ     1
SYSCALL_EXIT    equ     60

ASCII_ZERO      equ     0x30
ASCII_SPACE     equ     0x20


        section .rodata

src     db      'Podaj ciag znajow', 0x00       ;  String to convert
newline db      0x0a, 0x00                      ;  String for print_newline


        section .data

ach     db      'XXX ', 0x00                    ;  String for print_ascii


        section .text

;  Exits with success code.

exit_success:
        mov     rax, SYSCALL_EXIT
        mov     rdi, 0
        syscall


;  Calculates length of null-terminated string.
;  Arg 1 - address of string.
;  Returns - length of string.

string_length:
        push    rbp                     ;  Set up stack
        mov     rbp, rsp

        mov     rax, -1                 ;  Set character count to -1
        xor     rdx, rdx                ;  Zero register for character

.slloop:
        inc     rax                     ;  Increment character count
        mov     dl, BYTE [rdi+rax]      ;  Load character to dl
        cmp     dl, 0                   ;  If it's not the null character...
        jne     .slloop                 ;  ...keep counting.

        leave                           ;  Return character count
        ret


;  Outputs a null-terminated string to standard output.
;  Arg 1 - address of string.
;  No return value.

put_string:
        push    rbp                     ;  Set up stack
        mov     rbp, rsp
        sub     rsp, 16

        mov     [rbp-16], rdi           ;  Save address prior to func call

        call    string_length           ;  Get length of string
        mov     rdi, STDOUT             ;  First arg to write syscall
        mov     rsi, [rbp-16]           ;  Restore address to second arg
        mov     rdx, rax                ;  Third arg to write syscall
        mov     rax, SYSCALL_WRITE      ;  Load system call number
        syscall                         ;  Make system call

        leave                           ;  Return
        ret


;  Prints a numeric representation of a character's ASCII code.
;  Arg 1 - the character.
;  No return value.

print_ascii:
        push    rbp                     ;  Set up stack
        mov     rbp, rsp

        mov     rax, rdi                ;  Move character to rax
        mov     rcx, 10                 ;  Load rcx with divisor

        ;  Extract least significant digit

        xor     rdx, rdx                ;  Zero high-order bits for idiv
        idiv    rcx                     ;  Divide character by ten
        add     rdx, ASCII_ZERO         ;  Add '0' to remainder
        mov     BYTE [ach+2], dl        ;  Write third digit to string

        ;  Extract two most significant digits from quotient

        xor     rdx, rdx                ;  Zero high-order bits for idiv
        idiv    rcx                     ;  Divide by ten
        add     rax, ASCII_ZERO         ;  Add '0' to new quotient
        add     rdx, ASCII_ZERO         ;  Add '0' to new remainder

        ;  Write digits to string and print

        mov     BYTE [ach], al          ;  Write first digit to string
        mov     BYTE [ach+1], dl        ;  Write second digit to string

        lea     rdi, [ach]              ;  Load address of string
        lea     rsi, [ach+1]            ;  Prepare for conditional move
        cmp     rax, ASCII_ZERO         ;  If most significant digit is zero...
        cmove   rdi, rsi                ;  ...don't print it
        call    put_string              ;  Print ASCII representation

        leave                           ;  Return
        ret


;  Prints a newline
;  No arguments, no return value.

print_newline:
        push    rbp                     ;  Set up stack
        mov     rbp, rsp

        lea     rdi, [newline]          ;  Load address of newline string
        call    put_string              ;  Print it

        leave                           ;  Return
        ret


;  Entry point

_start:
        mov     rbp, rsp                ;  Set up stack
        sub     rsp, 16                 ;  Set up some local storage
        lea     rdi, [src]              ;  Load address of string

        call    put_string              ;  Print plain string first
        call    print_newline           ;  For tidy output
        lea     rdi, [src]              ;  Reload address after func call

.mainloop:
        movsx   rax, BYTE [rdi]         ;  Move a byte to rax
        cmp     rax, 0                  ;  If it's zero...
        je      .loopdone               ;  ...then we're done.

        mov     [rbp-16], rdi           ;  Save current string address
        mov     rdi, rax                ;  Pass character to function
        call    print_ascii             ;  Print representation of character
        mov     rdi, [rbp-16]           ;  Restore current string address
        inc     rdi                     ;  Increment current string address
        jmp     .mainloop               ;  Loop again

.loopdone:
        call    print_newline           ;  For tidy output
        call    exit_success            ;  Exit
输出:

paul@thoth:~/src/asm/scratch$ nasm -f elf64 -o stoa.o stoa.asm
paul@thoth:~/src/asm/scratch$ ld -o stoa stoa.o
paul@thoth:~/src/asm/scratch$ ./stoa
Podaj ciag znajow
80 111 100 97 106 32 99 105 97 103 32 122 110 97 106 111 119 
paul@thoth:~/src/asm/scratch$ 

显然,如果你真的想修改原始字符串,你必须为它留出更多的空间,因为你可以指望长度增加2到3倍,为所有数字腾出空间,甚至不包括任何空格。

我需要编写一个程序,将加载的字符串改为十进制符号。你打算把它改成什么?ASCII,从aaa,我应该得到65,如果你除以,比如说,65除以10,你会得到商6,余数5。如果将“0”的ASCII码添加到这两个字符中,则“6”和“5”的字符可以输出。