2

Trying to deal with my assignment of Assembly Language...

There are two files, hello.c and world.asm, the professor ask us to compile the two file using gcc and nasm and link the object code together.

I can do it under 64 bit ubuntu 12.10 well, with native gcc and nasm.

But when I try same thing on 64 bit Win8 via cygwin 1.7 (first I try to use gcc but somehow the -m64 option doesn't work, and since the professor ask us to generate the code in 64-bit, I googled and found a package called mingw-w64 which has a compiler x86_64-w64-mingw32-gcc that I can use -m64 with), I can get the files compiled to mainhello.o and world.o and link them to a main.out file, but somehow when I type " ./main.out" and wait for the "Hello world", nothing happens, no output no error message.

New user thus can't post image, sorry about that, here is the screenshot of what happens in the Cygwin shell:

enter image description here

I'm just a newbie to everything, I know I can do the assignment under ubuntu, but I'm just being curious about what's going on here?

Thank you guys

hello.c

//Purpose:  Demonstrate outputting integer data using the format specifiers of C.
//
//Compile this source file:     gcc -c -Wall -m64 -o mainhello.o     hello.c
//Link this object file with all other object files:  
//gcc -m64 -o main.out mainhello.o world.o
//Execute in 64-bit protected mode:  ./main.out
//

#include <stdio.h>
#include <stdint.h> //For C99 compatability

extern unsigned long int sayhello();

int main(int argc, char* argv[])
{unsigned long int result = -999;
 printf("%s\n\n","The main C program will now call the X86-64 subprogram.");
 result = sayhello();
 printf("%s\n","The subprogram has returned control to main.");
 printf("%s%lu\n","The return code is ",result);
 printf("%s\n","Bye");
 return result;
}

world.asm

;Purpose:  Output the famous Hello World message.


;Assemble: nasm -f elf64 -l world.lis -o world.o world.asm


;===== Begin code area 

extern printf    ;This function will be linked into the executable by the linker

global sayhello

segment .data    ;Place initialized data in this segment

          welcome db "Hello World", 10, 0
          specifierforstringdata db "%s", 10,


segment .bss    

segment .text   

sayhello:        

;Output the famous message
mov qword rax, 0       
mov       rdi, specifierforstringdata
mov       rsi, welcome
call      printf

;Prepare to exit from this function
mov qword rax, 0                                  
ret;                                              

;===== End of function sayhello     
nrz
  • 10,435
  • 4
  • 39
  • 71
hezzze
  • 31
  • 3
  • Does the cygwin-generated executable run on the linux system? Check file-sizes, and debug information. – Anirudh Ramanathan Jan 20 '13 at 22:34
  • Is the calling convention for `printf()` the same in both cases? Can you check that with, say, disassembly of `main()`? You could translate C code into assembly code with gcc with the `-S` switch. – Alexey Frunze Jan 20 '13 at 22:37
  • 1
    I would start by adding "fflush(stdout)" after the first printf - that way, you can see if you get to the sayhello or not. If that doesn't help, try using gdb! And Alexey makes a good point about calling convention. Windows is different from Linux, so you args should be in RCX, RDX, R8 and R9, rather RSI, RDI etc. Not sure if you need anyting in particular in eax or not. – Mats Petersson Jan 20 '13 at 22:48
  • Cygwin is buggy and unreliable. If you want to do Linux programming, use Linux. – Linuxios Jan 21 '13 at 01:34
  • Thanks guys, @MatsPetersson. So I added fflush(stdout) and it can help print out the first line, but the rest is not showing up. And I changed some code according to Mats: `mov qword rax, 0` `mov qword rax, 0` `mov rcx, specifierforstringdata` `mov rdx, welcome` `call printf` `mov qword rax, 0` It doesn't work though. I did more google, and found a thread with similar problem [http://stackoverflow.com/questions/561273/cygwin-assembly-language-development], which might indicates that doing this on windows is a no go.. – hezzze Jan 21 '13 at 06:08
  • @Cthulhu I tried to run the .out file on ubuntu it says cannot execute binary file – hezzze Jan 21 '13 at 06:52
  • @hezzze That would indicate that the output wasn't the same from the cygwin version. That doesn't seem right. Check using `hexdump` that it is a valid ELF executable generated. – Anirudh Ramanathan Jan 21 '13 at 07:48
  • Cygwin will generate a .exe file, so no, it won't run on ubuntu. Take a look at the code generated by the compiler. It should be possible to mix assembler and C - but you need to get everything right... – Mats Petersson Jan 21 '13 at 08:03
  • The mingw compiler generates native windows binary, you don't have to run it from a cygwin shell. Try a simple cmd window. – Jester Jan 21 '13 at 13:22

1 Answers1

1
;Purpose:  Output the famous Hello World message.
;Assemble: nasm -f win64 -o world.o world.asm

;===== Begin code area

extern _printf    ;This function will be linked into the executable by the linker
global _sayhello

segment .data    ;Place initialized data in this segment
          welcome db "Hello World", 0
          specifierforstringdata db "%s", 10, 0

segment .text

_sayhello:
;Output the famous message
sub       rsp, 40 ; shadow space and stack alignment
mov       rcx, specifierforstringdata
mov       rdx, welcome
call      _printf
add       rsp, 40 ; clean up stack

;Prepare to exit from this function
mov qword rax, 0
ret

;===== End of function sayhello

When linked together with the C wrapper in the question and run in plain cmd window it works fine:

screenshot

Depending on your toolchain you might need to remove the leading underscores from symbols.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • 1
    `sub rsp,32` should be `sub rsp, 40` to also re-align the stack by 16. (From RSP%16 == 8 on function entry, to RSP%16 == 0 required before a `call`.) Since your function doesn't need to `push` anything. Also, I thought Windows x64 didn't use leading underscores on C function names, unlike 32-bit, as in your NASM answer on [How To Properly call 64 Bit Windows API In Assembly](https://stackoverflow.com/q/24902157). But apparently this linked ok for you? – Peter Cordes Nov 22 '22 at 08:16
  • It certainly doesn't link now. Thanks for your comment. – Jester Nov 22 '22 at 12:11