如何在NASM中实现strncmp。我正在尝试在 asm 中实现我自己的 strcnmp。这是 nasm 代码:

问题描述 投票:0回答:1
section .text

global my_strncmp

my_strncmp:
    mov rcx, 0; using rcx like counter
.next:
    cmp rdx, rcx ; i think this comparing doesn't work (i have no idea with it) 
    je .return_0

    mov dh, byte [rdi]
    mov dl, byte [rsi]

    cmp byte [rdi], 0
    je .return_0 ;string ending
    
    cmp byte [rsi], 0
    je .return_0 ;string ending

    inc rcx
    inc rsi
    inc rdi

    cmp dh, dl
    je .next ; the loop continues until the string ends 
    jl .return_1
    jg .retrun_2

.return_0:
    mov rax, 0
    ret

.return_1:
    mov rax, 1
    ret

.retrun_2:
    mov rax, -1
    ret

我正在使用这个简单的 C 代码来运行 NASM

int main(){
    printf("%d\n", my_strncmp("string2", "string1", 3));
}

我的 strncmp 实际上和普通的 strcmp 一样工作(来自 C 标准库) 它没有从第 8 行跳转到 .return_0 标签)“cmp rdx, rcx”

c nasm strncmp
1个回答
0
投票

免责声明:此答案是由自然智能工具生成的。

  • 用高级编程语言编写
    if condition then
        result ≔ expression
    else
        result ≔ constant
    
    这是非常可读的。 然而,在汇编中,您经常采用分配默认值并“可能”稍后覆盖它的模式。 result ≔ constant if condition then result ≔ expression 我建议将
    rax
    设置为
    到目前为止
    确定的结果值,并有条件地退出该函数。 作为
  • 中间
  • 开发步骤,我建议使用长度前缀字符串(有时在流行的 Turbo Pascal 产品中被不准确地称为“Pascal 字符串”)。 哨兵终止的字符串可能会令人困惑,尤其是在汇编语言中编程时。 怎么样——仅用于开发——使用 string 数据类型来指示第一个字节中字符串的长度?
    my_strncmp("\x07string1", "\x0Astring1234", 3)
    
    一旦您的实现正常工作,您可以通过采用针对
    NUL
    终止字符串的算法来增加难度
    部分寄存器 
  • dh
  • dl
    是同一个
    D
    寄存器的一部分。
    dl
    (“D low”)是
    rdx
    edx
    dx
    的最低有效八位位组(全部同时出现,因为它是
    one
    寄存器)。 因此,写入dl也会影响您将来从
    rdx/edx
    /
    dx
    dl
    中读取的内容。
    可视化这种重叠的图表:
    
    ┌────────────────────────────────────────────────────────────────┐ │ ┌──────────────────────────────┐│ │ │ ┌────────────────┐││ │ `rdx` = entire 64-bit reg. │ `edx` = │ `dx` 16 bits │││ │ │ lower 32 │┌──────┐┌──────┐│││ M │ bits of ││ `dh` ││ `dl` │││L S │ entire ││ high ││ low │││S B │ 64-bit ││ 8 b ││ 8 b │││B │ │ register │└──────┘└──────┘│││ │ │ └────────────────┘││ │ └──────────────────────────────┘│ └────────────────────────────────────────────────────────────────┘
    x86-64 架构定义了一组附加 GPR(通用寄存器)
    r8
    r15
    。
    根据调用约定,必须存储和恢复您覆盖的值。
    我不熟悉 C – 您正在使用的编译器 – 但是在没有进一步预防措施的情况下使用 
    r8
    r9 可能
    没有问题。
        
© www.soinside.com 2019 - 2024. All rights reserved.