Author Topic: 64-bit equivalent  (Read 5432 times)

Offline denat

  • Jr. Member
  • *
  • Posts: 2
64-bit equivalent
« on: May 27, 2010, 04:07:02 AM »
Hi, trying to assemble, then link some code, which was 32-bit, had a problem with gcc when using -m32, there was an incompatible usage of the lgcc, so I'm trying to adjust it all to 64-bit (which is what my machine is). It's a learning app, purpose is to show how to use C libs. Two questions: is there something better to use than -m32 so I can make it 32 bit? Second, here's some code trying to convert:

push word [stdin]
push 72
push InString
call fgets
add esp, 12

(previously created extern stdin)

So, nasm says there's an error here. So I made it push qword [stdin]. Changing this and some other stuff, got it to assemble with no errors. But the executable doesn't do anything. I think it's supposed to. Maybe stdin has to be pushed as a word. Can push not push words?

Learning every second, great, have a good one,
Denat

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2381
  • Country: us
Re: 64-bit equivalent
« Reply #1 on: May 27, 2010, 02:41:19 PM »
Hi Denat,

Interesting questions! First, I think "-m32" is correct for gcc (to make 32-bit code). I think I've said "-m386" occasionally, but I think "-m32" is correct. Does it work? If we were invoking ld directly, I think "-melf-i386" is correct... but unless we use the "-c" switch, gcc will call ld for us, with the correct(?) command line.

Generally, we want "push" to push words in 16-bit code, dwords in 32-bit code (what you'd want, above), and qwords in 64-bit code. There are options, but apparently pushing dwords in 64-bit code isn't one of 'em. Don't be fooled by Nasm's "push byte imm" syntax - that stores the value as a byte, but sign-extends it to 16-, 32-, or 64-bit before pushing the "default" size - there is no way to push a byte!

However, that's not how you pass parameters in 64-bit code. First parameter goes in rcx, I think. Second in rdx(?), then r8(??), then r9)???). If there are more than a certain number of parameters, then they go on the stack. This differs between Windows and Linux!!! There are requirements for stack alignment, too. A real "cluster", IMHO!

64-bit is beyond my current hardware capabilities. Actually, there's a 64-bit machine sitting silent and cold, almost within arm's reach. Belongs to my roommate, who went out of town for a "couple weeks"... just before Christmas. I don't know when - or whether - he's coming back. Windows installed on it. I wouldn't format his hard drive, of course... not right away, at least... but I might try booting it from a 64-bit Linux cd someday soon... (I have no interest in running Windows, in any bitness... ever again... probably) If/when I do that, I'll be able to test some things...

Poke around the "examples" section - there are some 64-bit examples that may help you. I think it'll be easier to "learn" in 32-bit, but if your tool-chain isn't happy with that... (I don't even know what "lgcc" is!)...

For the code you show, "push dword [stdin]" would be correct for 32-bit. That's about the only part I'm sure of. :)

Here's an example of "hello world" for either 32- or 64-bit that the late Chuck Crayne left for us to learn from before he passed. It doesn't call libc, and may not be what you want, but maybe it'll help somebody...

Best,
Frank


Offline denat

  • Jr. Member
  • *
  • Posts: 2
Re: 64-bit equivalent
« Reply #2 on: May 31, 2010, 10:06:15 PM »
Hi Frank,

Yeah, -m32 works well, it seems. Your response was positive, so the stack can only have 64bits pushed onto it, in 64-bit mode.

Here's a link from the examples that you suggested: http://forum.nasm.us/index.php?topic=342.0 . I'll adjust the app I have with what is said here, especially the register order which is a bit different on the 64bit side.

Could read some more examples, and display from gcc the AT&T asm file of what is being done here in C, as a backup.

Want to get this part rolling! See u later,
Denat