提问人:Charlie Benger-Stevenson 提问时间:11/8/2023 最后编辑:Peter CordesCharlie Benger-Stevenson 更新时间:11/8/2023 访问量:41
将值从寄存器复制到变量 x86-64 时出现问题
Problem copying value from register to variable x86-64
问:
我正在尝试将传递给我的简单汇编语言程序的命令行参数存储在变量中以供以后使用。
global _start
section .text
_start:
pop rax ; argc
cmp rax,1 ; no command line arguments supplied
jz begin
get_cmdln_args:
pop rax ; argv
pop rax ; arg[1]
cmp byte [rax], '-'; test string first char for - character
jz parse_option ;
pop rax ; arg[2]
pop rax ; arg[3]
parse_option:
cmp byte [rax +1], 'p'
jz portarg
portarg:
pop rax
mov [port], rax
portargl:
cmp byte [rax], $0
jz get_cmdln_args
inc rax
jnz portargl
begin:
mov rax, 1 ; write(
mov rdi, 1 ; STDOUT_FILENO,
mov rsi, msg ; "Hello, world!\n",
mov rdx, msglen ; sizeof("Hello, world!\n")
syscall ; );
mov rax, 60 ; exit(
mov rdi, 0 ; EXIT_SUCCESS
syscall ; );
section .bss
port: resb 8
section .rodata
msg: db "Hello, I am from the Isle of Mann!", 10
msglen: equ $ - msg
问题出在 portarg 标签上。
在 GDB 中,我可以看到 RAX 的值是“8080”,这是在命令行上指定的值,因此
gdb --args hello -port 8080
启动调试器,我可以看到堆栈上的命令行参数。 弹出堆栈后,我可以看到 RAX 中的命令行参数。
执行 mov 指令后,我仍然可以在 RAX 中看到“8080”,但存储在我的变量中的内容看起来很可疑。
变量的地址为 0x403024
x/s 0x403024
返回
"\222\342\377\377\377\177"
这是怎么回事?
我怎样才能在这个地址将其存储为整数?我见过你这样做的例子
子 RAX, '0'
删除尾随的 0,然后将其视为整数。如果我在这里尝试,我会得到一个空字符串。
答:
1赞
Melvin
11/8/2023
#1
误解是您试图将命令行参数作为整数存储在内存中。然而,如果你使用'pop rax',它是由一个字符串表示的。解决方案相当简单:您需要手动将字符串转换为整数。确保将计算值另存为四字字。基本例程可能如下所示:
str_to_int:
; Convert a null-terminated string in rdi to an integer in rax
xor rax, rax ; Clear rax to store the result
xor rcx, rcx ; Clear rcx to use as a counter
convert_loop:
movzx rbx, byte [rdi + rcx] ; Load the next character
test rbx, rbx ; Check if it's the null terminator
jz done_conversion ; If it is, we are done
sub rbx, '0' ; Convert ASCII to integer
imul rax, rax, 10 ; Multiply current result by 10
add rax, rbx ; Add the new digit
inc rcx ; Move to the next character
jmp convert_loop
done_conversion:
ret
评论
2赞
Peter Cordes
11/8/2023
RBX 在标准调用约定中保留调用;你可以在那里使用 RDX。例如 / 将零扩展到 RDX 并递增指针。(不需要单独的寄存器索引)。NASM 程序集将输入转换为整数?显示此循环的一个版本,条件分支位于底部,以第一个非数字字符结尾。movzx edx, byte [rdi]
inc rdi
评论