4 ms·
Is it explained where the values for ecx and edx get filled in? I'm confused as to why edx=0x080480B1 instead of the length of the string (14).
by abbeyj 13y ago
Is it explained where the values for ecx and edx get filled in? I'm confused as to why edx=0x080480B1 instead of the length of the string (14).
- arh68 13y agoIt's the HWLENADDR you're talking about? It's placed as the last byte in (not in: after) the string. Down in the final product the edx part ends up BA B1 80 04 08 (0x080480B1). It's a pointer to that '14' stored 13 bytes past the start of the string ("hello, world\n" is 13 bytes). The ecx points to (0x..A4), exactly 13 less than B1. edit: You're probably thinking it should be placed as an immediate value. It's hard to say exactly how many bytes it'd take up that way, so using an address to an immediate value is a bit simpler.
- abbeyj 13y agoI see where I was off by one byte (14 instead of 13) but that still doesn't explain things. The code doesn't load edx with 13 but instead loads it with 0x080480B1. If you wanted to fetch a byte from that address and load it into edx you'd need to use something like "movzx edx, byte ptr [0x080480B1]" but the code on the page just does "mov edx, 0x080480B1". In fact when you run this the code actually prints out not just "Hello, World\n" but also prints out the 0x0D length byte and then the entire rest of the page (all 0x00). Of course these aren't visible in a terminal. I'm guessing the kernel tries to keep printing but it can't since the next page isn't mapped so it just gives up.
- deleted 13y ago[deleted]
- adestefan 13y agoI agree. This is definitely a bug. The correct instruction is 8b 15 B1800408 or a MOV EDX, [0x080480B1]. I hope I got my register number correct on that. The movzx/movsx is only needed when you're doing something like movzx EAX, BX. That way you're sure the CPU does what you expect when moving from a smaller register to a larger one. Man do I hate x86.
- arh68 13y agoYeah, you're right. The syscall does ask for a size_t. It now looks correct. The whole length-after-the-string part is edited out, and the value is indeed placed as immediate (as the syscall wants). Now the binary ends with "hello, world\n" and 14 is inserted directly (b9 a4 80 04 08, ba 0d 00 00 00).
- robinh 13y agoAuthor here. And yes, that's a bug. I recently restored most of the pages on my website, and didn't check whether each page was the most recent version. When I first wrote the HOWTO, I for some reason was under the impression that the 'write' system call required the address of the length of the string to be loaded in EDX, which is obviously a bit silly. You're right that EDX should just hold the value 13. I'll change this as soon as I get the time.