Assembly 汇编程序加载的字符串到十进制表示法
我需要编写一个程序,将加载的字符串更改为十进制符号,并在控制台上写入我们接收到的内容,现在在这段代码中只有echo工作,如何在内存中移动以更改我们接收到的字符串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 =
.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”的字符可以输出。