将用户输入字符转换为符号:x86_64 程序集
Convert User Input Character to Symbol: x86_64 Assembly
我正在尝试将输入字符转换为 x86 程序集中的输出符号。例如,如果用户输入 A
我希望输出以下内容:
$
$ $
$$$$$
$ $
$ $
对于B
:
$$$$
$ $
$$$$
$ $
$$$$
等我目前的方法是设置一串 0 和 1,然后循环并将 0
转换为 space,将 1
转换为 $
。我使用 b
作为换行符(即新行)和 x
作为字符串的结尾。
我下面的代码(只显示 A
运行 以缩短代码):
section .data
; constants
NULL equ 0
EXIT_SUCCESS equ 0
EXIT_FAIL equ 1
SYS_exit equ 60
SYS_read equ 0
SYS_write equ 1
STD_in equ 0
STD_out equ 1
; other
text1 db "Please enter an upper-case letter from A-E: ",0
errmsg db "Error: incorrect letter chosen.",0
sucmsg db "Success.",0
symA db "00100b01010b11111b10001b10001x ",0
space db " "
dollar db "$"
lbreak db "b"
lend db "x"
section .bss
; reserve space for user input
letter resb 1
section .text
global _start
_start:
; print question
mov rax, text1
call _printText
; get user input
; sys_read (0, latter, 1)
mov rax, SYS_read
mov rdi, STD_in
mov rsi, letter
mov rdx, 1
syscall
; dereference rsi
movzx rsi, byte [letter]
; jump conditionals
mov rdx, "A"
cmp rsi, rdx
je _printA
; default jump if no match
; print fail msg
mov rax, errmsg
call _printText
jmp _exitFail
_printA:
xor eax, eax
; sys_write (1, text, 1)
mov rax, symA
call _printText
call _printChar
jmp _exitSuccess
_exitFail:
; default error exit
; sys_exit (1)
mov rax, SYS_exit
mov rdi, EXIT_FAIL
syscall
_exitSuccess:
; print success msg
mov rax, sucmsg
call _printText
; sys_exit (0)
mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall
; functions
_printText:
push rax
mov rbx, 0
_ptLoop:
inc rax
inc rbx
mov cl, [rax]
cmp cl, 0
jne _ptLoop
mov rax, SYS_write
mov rdi, STD_out
pop rsi
mov rdx, rbx
syscall
ret
_printChar:
;push rax
mov rbx, 0
_pcLoop:
inc rax
inc rbx
mov cl, [rax]
; if 0
cmp cl, 0
je _movSpace
; if 1
cmp cl, 1
je _movSymbol
; if newline
cmp cl, lbreak
je _movNewLine
; if end
cmp cl, lend
je _endPrint
_movSpace:
mov rcx, space
loop _pcLoop
_movSymbol:
mov rcx, dollar
loop _pcLoop
_movNewLine:
mov rcx, "\n"
loop _pcLoop
_endPrint:
mov rax, SYS_write
mov rdi, STD_out
mov rsi, rcx
mov rdx, rbx
syscall
ret
目前,我尝试调试,因为我在 _printChar
函数中得到 Segmentation fault (core dumped)
,但是,现在使用上面的代码我无法创建可执行文件,因为它返回以下错误:
(.text+0x10e): relocation truncated to fit: R_X86_64_8 against '.data'
(.text+0x113): relocation truncated to fit: R_X86_64_8 against '.data'
在终端中尝试运行以下命令时:
ld filename.o -o filename
任何人都可以提出任何建议来帮助上面的代码实现我所追求的 objective 吗?
我假设你用
制作你的程序
nasm -f elf64 filename.asm -o filename.o -l filename.lst
ld filename.o -o filename
链接器在 .text+0xca
处报告了一个问题,因此您需要在 .text
部分的“filename.lst”中找到在该偏移量 0xca
处生成的指令:
....
112 000000C3 80F901 cmp cl, 1
113 000000C6 7416 je _movSymbol
114 ; if newline
115 000000C8 80F9[78] cmp cl, lbreak
116 000000CB 741D je _movNewLine
117 ; if end
118 000000CD 80F9[79] cmp cl, lend
119 000000D0 741F je _endPrint
....
是cmp cl, lbreak
。查看定义 lbreak db "b"
很明显,您的指令错误地尝试将 cl
中的字节值与部分中变量 lbreak
的 offset 进行比较.data
,正好是78。您可能打算将 cl
与存储在内存中的 value "b"
进行比较,使用 cmp cl, [lbreak]
或什至更好,使用 immediate 值:cmp cl,"b"
.
还可以考虑将大字母打印为一个以 0 结尾的字符串,使用单个 _printText
:
SECTION .data
BigA DB " $ ",10
DB " $ $ ",10
DB "$$$$$",10
DB "$ $",10
DB "$ $",10
DB 0
BigB DB "$$$$ ",10
DB "$ $",10
DB "$$$$ ",10
DB "$ $",10
DB "$$$$ ",10
DB 0
我正在尝试将输入字符转换为 x86 程序集中的输出符号。例如,如果用户输入 A
我希望输出以下内容:
$
$ $
$$$$$
$ $
$ $
对于B
:
$$$$
$ $
$$$$
$ $
$$$$
等我目前的方法是设置一串 0 和 1,然后循环并将 0
转换为 space,将 1
转换为 $
。我使用 b
作为换行符(即新行)和 x
作为字符串的结尾。
我下面的代码(只显示 A
运行 以缩短代码):
section .data
; constants
NULL equ 0
EXIT_SUCCESS equ 0
EXIT_FAIL equ 1
SYS_exit equ 60
SYS_read equ 0
SYS_write equ 1
STD_in equ 0
STD_out equ 1
; other
text1 db "Please enter an upper-case letter from A-E: ",0
errmsg db "Error: incorrect letter chosen.",0
sucmsg db "Success.",0
symA db "00100b01010b11111b10001b10001x ",0
space db " "
dollar db "$"
lbreak db "b"
lend db "x"
section .bss
; reserve space for user input
letter resb 1
section .text
global _start
_start:
; print question
mov rax, text1
call _printText
; get user input
; sys_read (0, latter, 1)
mov rax, SYS_read
mov rdi, STD_in
mov rsi, letter
mov rdx, 1
syscall
; dereference rsi
movzx rsi, byte [letter]
; jump conditionals
mov rdx, "A"
cmp rsi, rdx
je _printA
; default jump if no match
; print fail msg
mov rax, errmsg
call _printText
jmp _exitFail
_printA:
xor eax, eax
; sys_write (1, text, 1)
mov rax, symA
call _printText
call _printChar
jmp _exitSuccess
_exitFail:
; default error exit
; sys_exit (1)
mov rax, SYS_exit
mov rdi, EXIT_FAIL
syscall
_exitSuccess:
; print success msg
mov rax, sucmsg
call _printText
; sys_exit (0)
mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall
; functions
_printText:
push rax
mov rbx, 0
_ptLoop:
inc rax
inc rbx
mov cl, [rax]
cmp cl, 0
jne _ptLoop
mov rax, SYS_write
mov rdi, STD_out
pop rsi
mov rdx, rbx
syscall
ret
_printChar:
;push rax
mov rbx, 0
_pcLoop:
inc rax
inc rbx
mov cl, [rax]
; if 0
cmp cl, 0
je _movSpace
; if 1
cmp cl, 1
je _movSymbol
; if newline
cmp cl, lbreak
je _movNewLine
; if end
cmp cl, lend
je _endPrint
_movSpace:
mov rcx, space
loop _pcLoop
_movSymbol:
mov rcx, dollar
loop _pcLoop
_movNewLine:
mov rcx, "\n"
loop _pcLoop
_endPrint:
mov rax, SYS_write
mov rdi, STD_out
mov rsi, rcx
mov rdx, rbx
syscall
ret
目前,我尝试调试,因为我在 _printChar
函数中得到 Segmentation fault (core dumped)
,但是,现在使用上面的代码我无法创建可执行文件,因为它返回以下错误:
(.text+0x10e): relocation truncated to fit: R_X86_64_8 against '.data'
(.text+0x113): relocation truncated to fit: R_X86_64_8 against '.data'
在终端中尝试运行以下命令时:
ld filename.o -o filename
任何人都可以提出任何建议来帮助上面的代码实现我所追求的 objective 吗?
我假设你用
制作你的程序nasm -f elf64 filename.asm -o filename.o -l filename.lst
ld filename.o -o filename
链接器在 .text+0xca
处报告了一个问题,因此您需要在 .text
部分的“filename.lst”中找到在该偏移量 0xca
处生成的指令:
....
112 000000C3 80F901 cmp cl, 1
113 000000C6 7416 je _movSymbol
114 ; if newline
115 000000C8 80F9[78] cmp cl, lbreak
116 000000CB 741D je _movNewLine
117 ; if end
118 000000CD 80F9[79] cmp cl, lend
119 000000D0 741F je _endPrint
....
是cmp cl, lbreak
。查看定义 lbreak db "b"
很明显,您的指令错误地尝试将 cl
中的字节值与部分中变量 lbreak
的 offset 进行比较.data
,正好是78。您可能打算将 cl
与存储在内存中的 value "b"
进行比较,使用 cmp cl, [lbreak]
或什至更好,使用 immediate 值:cmp cl,"b"
.
还可以考虑将大字母打印为一个以 0 结尾的字符串,使用单个 _printText
:
SECTION .data
BigA DB " $ ",10
DB " $ $ ",10
DB "$$$$$",10
DB "$ $",10
DB "$ $",10
DB 0
BigB DB "$$$$ ",10
DB "$ $",10
DB "$$$$ ",10
DB "$ $",10
DB "$$$$ ",10
DB 0