You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86-64汇编:命令行参数转整数存入变量失败问题排查

命令行参数存储与字符串转整数问题分析与解决

问题原因

  • 存储参数后x/s查看乱码:你将命令行参数的内存地址存入了port变量,但调试时直接用x/s 0x403024是把port变量自身的字节当作字符串解析。port里存的是64位地址值,不是ASCII字符序列,自然显示乱码。正确操作应该是把port里的内容当作地址,再读取对应内存的字符串。
  • sub rax, '0'得到空字符串:rax里是字符串的内存地址,不是单个字符的ASCII值。直接对地址做减法会得到无效内存地址,读取该地址内容自然为空或乱码。字符串转整数需要逐个处理每个字符,而非对地址操作。

解决方法

一、正确存储命令行参数地址并验证

x86_64 Linux程序启动后,栈布局为:argc → argv[0](程序名地址)→ argv[1](第一个参数地址)→ ... → NULL。若已通过pop rax拿到参数"8080"的地址:

  1. 执行mov [port], rax将地址存入变量,这一步本身是正确的。
  2. 调试查看参数内容时,需用GDB命令x/s *(char**)0x403024——该命令会先取出port变量里的地址值,再读取对应地址的字符串。

二、正确将字符串参数转为整数存入port

需要逐个遍历字符串的每个字符,转为数字后累加计算。示例汇编代码(nasm语法,x86_64 Linux):

section .data
port dq 0        ; 定义64位变量存储最终整数

section .text
global _start
_start:
    ; 从栈中取出第一个命令行参数地址
    pop rdi        ; rdi = argc
    pop rsi        ; rsi = argv[0](程序名)
    pop rsi        ; rsi = argv[1](目标参数地址)

    xor rdx, rdx   ; 初始化结果寄存器为0
convert_loop:
    mov bl, [rsi]  ; 读取当前字符到bl
    test bl, bl    ; 判断是否到达字符串结束符
    jz convert_done

    sub bl, '0'    ; 将ASCII字符转为数字(0-9)
    imul rdx, 10   ; 结果乘以10,为新数字腾出位置
    add rdx, rbx   ; 加上当前数字(rbx是bl的零扩展)
    inc rsi        ; 指针移动到下一个字符
    jmp convert_loop

convert_done:
    mov [port], rdx ; 将最终整数存入port变量

    ; 程序退出逻辑
    mov rax, 60
    xor rdi, rdi
    syscall

调试验证

  • 执行到convert_done时,rdx寄存器的值为十进制8080(十六进制0x1f90)
  • 用GDB命令x/q 0x403024查看port变量,会显示0x0000000000001f90,对应十进制8080

内容的提问来源于stack exchange,提问作者Charlie Benger-Stevenson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 15:22:48