Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 在程序集中的字符串上迭代(NASM)_String_Memory_Assembly_Nasm_Memory Address - Fatal编程技术网

String 在程序集中的字符串上迭代(NASM)

String 在程序集中的字符串上迭代(NASM),string,memory,assembly,nasm,memory-address,String,Memory,Assembly,Nasm,Memory Address,我试图用NASM汇编语言计算字符串argv[1]的长度。我想我走对了。我已经将argv[1]的地址移到了寄存器eax,现在我想逐字节地遍历它,并与空字符串终止符进行比较 每次我运行代码时,它都会在空比较中出错。我的内存索引是否正确 *免责声明:这是大作业的一小部分 segment .bss N: resd 1 ;counter for size of argv[1] segment .text global asm_main asm_main: en

我试图用NASM汇编语言计算字符串argv[1]的长度。我想我走对了。我已经将argv[1]的地址移到了寄存器eax,现在我想逐字节地遍历它,并与空字符串终止符进行比较

每次我运行代码时,它都会在空比较中出错。我的内存索引是否正确

*免责声明:这是大作业的一小部分

segment .bss

N: resd 1                 ;counter for size of argv[1]

segment .text
  global asm_main

asm_main:
  enter 0,0               ;setup
  pusha                   ;save all registers

  mov eax, dword [ebp+8]  ;argc to eax

  mov ebx, dword [ebp+12] ; address of argv to ebx
  mov eax, dword [ebx+4]  ; address of argv[1] to eax

  mov [N], dword 0        ; N = 0 

  .loop:

    add eax, [N]          ; advance index by N
    cmp eax, dword 0      ; check for end of string
    je .endloop           ; break out of the loop if we're done


    add [N], dword 1      ; N++    

    jmp .loop             ; loop back for next char

  .endloop:

popa
mov eax, 0
leave
ret

在一些提示和gdb的帮助下,循环现在看起来如下所示:

  mov [N], dword 0        ; N = 0 

  .loop:

    cmp [eax], byte 0     ; check for end of string
    je .endloop    

    add eax, dword 1      ; advance index by 1 byte
    add [N], dword 1      ; N++    

    jmp .loop             

  .endloop:

使用N来增加索引是愚蠢的。我需要增加1。

它实际上是在哪个指令上启动的
addeax,[N]
从固定地址读取数据,因此如果它第一次没有SEGFULT,它就永远不会SEGFULT。使用调试器进行单步调试,查看出现故障时regs/mem中的内容。这里最明显的问题是,您从不读取字符串,只需增加一个指针并将其与零进行比较。(并且您以几何方式递增eax,因为
[N]
线性递增。)它在cmp线上消亡。你是对的,我上面的这行比较了地址(希望是字符的地址)和期望值,而不是字符本身。我应该有cmp[eax],dword 0吗?字符串应该是[byte][byte][byte]…[null]。所以不是dword,而是字节。EAX应该将地址保存到字节。[EAX]应该是有问题的字节。cmp[eax],字节0?@PeterCordes当我在调试器上看到它时,我只是/面对它。请注意,您不需要单独的计数器。您只需执行
子eax,在循环后启动\u字符串的\u即可。(如果可以避免,请不要将循环计数器保留在内存中。它非常慢。在大多数英特尔CPU上,代码的运行速度几乎是在寄存器中保留N(或完全避免)时的6倍),因为它将存储/重新加载往返放入循环携带的依赖链中,并且在Intel SnB系列CPU上存储转发延迟为5个周期。)。虽然我很感激您知道所使用数据的大小,但JFYI:the
add eax,dword 1
不需要大小说明符,因为一侧的
eax
强制执行指令的32b大小的上下文。因此,在这种情况下,添加eax,1就足够了。下面的一个是正确的,dword 1至少在一侧需要大小说明符,因为没有它是不明确的,如果
N
只是字节/字,那么
byte
word
也有意义。要执行+-1操作,x86具有专用的操作码
inc
dec
,保存了该
,1
的键入。不知道为什么我真的喜欢这两个