如何在 x86_64 中循环创建字符串
How to create string in loop in x86_64
我有一个字符串,我想将该字符串中的任何符号转换为另一个(例如,将“a”转换为“4”,将“e”转换为“3”等)。
逻辑:
i) 使用 db
定义的字符串变量
ii) 使用resb
定义的字符串变量将转换后的字符传输到
iii) 遍历第一个字符串并使用 cmp
根据需要转换字符
iv) while循环将转换后的字符存储在第二个变量中
v) 打印第二个转换后的字符串
我目前的尝试:
section .data
; constants
EXIT_SUCCESS equ 0
SYS_exit equ 60
SYS_read equ 0
SYS_write equ 1
; variables
sym db "01010",10,"$"
text0 db " "
text1 db "$"
text2 db "",10
section .bss
; reserve space for output symbol
symbol resb 6
section .text
global _start
_start:
mov rax, sym
call _print
mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall
_print:
mov rbx, 0 ; use rbx to count len(string)
_printLoop:
inc rax
inc rbx
mov cl, [rax] ; will hold next char in string
cmp cl, "0" ; if 0 add space
je _addT0
cmp cl, "1" ; if 1 add $ symbol
je _addT1
cmp cl, "$" ; if end of string
je _continuePrint
mov symbol[rbx], text3 ; default: add new line
jmp _printLoop
_addT0:
mov symbol[rbx], text0
jmp _printLoop
_addT1:
mov symbol[rbx], text1
jmp _printLoop
_continuePrint:
mov rax, 1
mov rdi, 1
mov rsi, symbol
mov rdx, rbx ; use rbx as count
syscall
ret
例如,如果 sym
是 "01010"
,我希望输出 sym
等于 " $ $ "
。
在 _printLoop:
处递增 rax
使您始终忽略输入字符串的第一个字符。在使用 eax
中的地址后,推迟递增:
_printLoop:
inc rbx
mov cl, [rax] ; will hold next char in string
inc rax ; Prepare EAX to point at the next character.
...
像mov symbol[rbx], text0
这样的指令是错误的,因为text0
表示text0
的地址,而不是它的内容.
将text0 db " "
重新定义为text0 equ " "
,这将使它成为一个值(立即数" "
别名0x20)而不是内存变量。类似 text1 equ "$"
和 text2 equ 10
。
正确的 NASM 语法是 then
mov byte [symbol+rbx], text2 ; default: add new line.
我有一个字符串,我想将该字符串中的任何符号转换为另一个(例如,将“a”转换为“4”,将“e”转换为“3”等)。
逻辑:
i) 使用 db
ii) 使用resb
定义的字符串变量将转换后的字符传输到
iii) 遍历第一个字符串并使用 cmp
根据需要转换字符
iv) while循环将转换后的字符存储在第二个变量中
v) 打印第二个转换后的字符串
我目前的尝试:
section .data
; constants
EXIT_SUCCESS equ 0
SYS_exit equ 60
SYS_read equ 0
SYS_write equ 1
; variables
sym db "01010",10,"$"
text0 db " "
text1 db "$"
text2 db "",10
section .bss
; reserve space for output symbol
symbol resb 6
section .text
global _start
_start:
mov rax, sym
call _print
mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall
_print:
mov rbx, 0 ; use rbx to count len(string)
_printLoop:
inc rax
inc rbx
mov cl, [rax] ; will hold next char in string
cmp cl, "0" ; if 0 add space
je _addT0
cmp cl, "1" ; if 1 add $ symbol
je _addT1
cmp cl, "$" ; if end of string
je _continuePrint
mov symbol[rbx], text3 ; default: add new line
jmp _printLoop
_addT0:
mov symbol[rbx], text0
jmp _printLoop
_addT1:
mov symbol[rbx], text1
jmp _printLoop
_continuePrint:
mov rax, 1
mov rdi, 1
mov rsi, symbol
mov rdx, rbx ; use rbx as count
syscall
ret
例如,如果 sym
是 "01010"
,我希望输出 sym
等于 " $ $ "
。
在 _printLoop:
处递增 rax
使您始终忽略输入字符串的第一个字符。在使用 eax
中的地址后,推迟递增:
_printLoop:
inc rbx
mov cl, [rax] ; will hold next char in string
inc rax ; Prepare EAX to point at the next character.
...
像mov symbol[rbx], text0
这样的指令是错误的,因为text0
表示text0
的地址,而不是它的内容.
将text0 db " "
重新定义为text0 equ " "
,这将使它成为一个值(立即数" "
别名0x20)而不是内存变量。类似 text1 equ "$"
和 text2 equ 10
。
正确的 NASM 语法是 then
mov byte [symbol+rbx], text2 ; default: add new line.