使用64位寄存器比较nasm x86-64中的字符



我是x86_64编码的新手,正在探索各种代码。

我正在尝试比较nasm x86_64代码中的字符"a",但比较结果不相等。

; Tests the command line. Similar to a C main function:
;  int main(int argc, char** argv)
;
; - argc, number of args in rdi
; - argv, pointer to pointer in rsi and argv
global  main
extern  puts
main:
mov     rbp, rdi      ; argc in rdi. Save in rbp, caller-saved
mov     rbx, rsi      ; argv in rsi. Save in rbx, caller-saved

add     rbx, 8
dec     rbp
mov     rdi, [rbx]
cmp     rdi, 'A'
je      exit1
call    puts
mov     rax, 0
ret
exit1:  
mov     rax, 1
ret

如何修改代码以获得所需的结果?有一些解决方案,但它使用了8位寄存器,正如这里所用的那样,比较汇编、nasm中的字符,但为了澄清我的基本知识,我想了解为什么像我的代码这样的直接比较不起作用。

  • argv是指向以null结尾的字符串的指针列表的指针。在顶部,您必须首先取消引用指针mov rbx, [rsi],这样您实际上是在检查*char值的列表。

  • 引用英特尔关于cmp:的指令参考,cmp操作数的大小(实际上对于几乎所有指令(都很重要

    当立即数用作操作数时,它会被符号扩展到第一个操作数的长度。

    您实际上是在比较两个64位数量。

  • (至少(有两种可能的解决方案:

    • cmp dil, 'A':您仍然可以一次从内存中检索8个字节,但为了进行比较,您需要指定一个部分寄存器
    • cmp之前插入movsx rdi, dil(或与一步movsx rdi, byte [rbx]中的fetch组合(:正如Jester所建议的,您仍然可以执行64位比较,但要确保高位设置正确
  • 写入cmp rdi, 'A'是写入cmp rdi, 0x41的替代方案。在执行时,0x41得到符号扩展,因此您最终将0x00000041rdi的内容进行比较。现在,如果您以前从[rbx]加载八个字节,则上面的七个字节可能会填充有胡言乱语,或者说,char字符串中后面的字符。这会给你带来麻烦。

  • 旁注:说到参数传递,我不确定是否可以这样调用putsrdi不应该包含以null结尾的字符串的地址吗?

相关内容

  • 没有找到相关文章

最新更新