0

I'm here with what is probably a very basic question, but I haven't been able to find many resources out there for the assembly I'm working with (YASM assembler, targeting 64-bit Intel CPUs [“x86-64”] on Linux).

As part of a program I'm writing, I need to write a function that receives a char* in rdi to the beginning of a string, and a char* in rsi to a "substring" that I must search for within the first string. It is supposed to "return" the first occurrence of where the substring is within the main string by setting [byte]rax to null (0 using ASCII).

Right now I am simply trying to return 0, or null, regardless of if the substring is present or not, and then figure out the rest after. When it didn't seem to be working, I tried this...

mov byte[rax], 0
cmp byte[rax], 0
je .not_found

...along with other variations, all very similar to each other. Of course if I do something like...

mov rax, 0
cmp rax, 0
je .not_found

...then it works, so what I'm not understanding is what I should be doing differently when targeting a single byte to set to 0 (as opposed to an entire 64 bit register), and checking this.

Any help would be appreciated, and I apologize if I wasn't being technically correct when describing what's happening, as assembly is still fairly new to me. Thank you!

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Christopher M
  • 99
  • 2
  • 7
  • My reading of this is *return" the first occurrence* by inserting a terminating `0` byte into the main string, at the *end* of a match. (Assuming that you'd be using `rax` to hold a pointer to the current search position). Remember that C strings are implicit length, terminated by a `0`. (That's called ASCII NUL, not NULL. NULL with two ells is the name of a pointer constant.) – Peter Cordes Dec 13 '19 at 10:36
  • Anyway, what didn't work? Those are both valid syntax, but the first one depends on RAX being a valid pointer (and doesn't modify it). The cmp/je part is pointless in both; might as well just JMP after you already decided you found a match; there's no more comparing left to be done. – Peter Cordes Dec 13 '19 at 10:40
  • In the first example of code, the comparison is showing they are not equal, or at least it seems this way because it does not then do the je .not_found ...However in the second snippet of code, the je .not_found is true. So the first instance does not do the jump, but the second one does. The problem itself will be more complex than this, and I will instead be moving a byte from a string into rax rather than setting it to 0 manually. But when that wasn’t working as I thought it should, I noticed this weird problem, and wasn’t sure what to do about it – Christopher M Dec 13 '19 at 18:17
  • Unless it segfaults first, your first example *will* jump to `.not_found`, same as your 2nd block, just with different side effects. If it doesn't, you tested it wrong. Make sure you're single-stepping by instruction in your debugger. If you can still reproduce that branch being not-taken, reduce it to a runnable [mcve] of a `_start` or `main`, and the steps you used to test whether it was taken or not. (And [edit] your question with those details.) – Peter Cordes Dec 13 '19 at 18:44

0 Answers0