-1

I am attempting to learn assembly using Mac OSX, however, I am running into invalid operand errors. Currently, I am attempting to create a simple for loop to 10 in assembly, the equivalent of the following in c++:

for(int i = 0; i < 10; i++){
}

My current assembly (simpleloop.s):

.globl _main

_main:
  pushq %rbp
  movq %rsp, %rbp
  subq $16, %rsp
  movl $10, %cx
  loop:
    dec %cx
    jnz loop
  leave
  ret

However, when I run this snipped using gcc simpleloop.s, I receive the following error message:

error: invalid operand for instruction movl $10, %cx

I realize that questions regarding the creation of for-loops in assembly have been asked many times on StackOverflow, however, I am unable to find any question or answer regarding for-loops with assembly specific to Mac OSX. Can anyone explain why I am receiving the error and how it can be corrected? It appears to me that Mac OSX only accepts x86 using the "AT&T" syntax. Can anyone tell me why this is?

Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • `cx` is not a 32 bit register. – tkausl Apr 30 '18 at 21:04
  • @tkausl I did not know that. Is assembly with Mac 64 bit instead? – Ajax1234 Apr 30 '18 at 21:07
  • 1
    @Ajax1234 You are already programming 64 bit code as the use of registers `rsp` and `rbp` indicates. Please grab an assembly tutorial before continuing, you seem to be lacking in the foundations. – fuz Apr 30 '18 at 21:45
  • @fuz I certainly am. Unfortunately, I have not been able to find any comprehensive tutorials on the web specifically in AT&T syntax or assembly specifically for MacOSX, hence my struggles with the basics of Assembly itself. Do you know of any resources that may be best for Mac? I have not been any find any guides except for Intel Assembly, which does not work on Mac. – Ajax1234 Apr 30 '18 at 21:50
  • @Ajax1234 I'm not sure what tutorial is best; you can just use a Linux tutorial and note that symbols are decorated and system calls work differently on macOS. As you should never do system calls on your own (use the libc wrappers instead), the latter is less important. – fuz Apr 30 '18 at 21:55
  • @Ajax1234: NASM works on MacOS (modulo [a couple bugs with MachO64 object files in some NASM versions](https://stackoverflow.com/questions/45057358/incorrect-nasm-indirect-addressing-assembly-on-macos#comment86890289_45057358)). No reason you have to use AT&T syntax if you'd rather learn Intel syntax first / instead, so you can more easily read Intel's official instruction-set reference manual and so on. The underlying machine code is the same, of course; it's just different asm syntax to talk about the same machine encodings. – Peter Cordes May 01 '18 at 02:25

1 Answers1

2

Looking at this instruction:

movl $10, %cx

movl stands for move long, i.e. move 32 bits. %cx however is a 16-bit register. Thats why your assembler is complaining. Either move to the 32-bit register %ecx or use the 16-bit move instruction movw. Or, just use mov, since your assembler can deduce the size from your register-operand.

tkausl
  • 13,686
  • 2
  • 33
  • 50
  • Ah, phenomenal, it works. Thank you! As a quick aside, my current code does nothing, accept move the bits. Is there any way to display a message such as `"hello"` at each iteration of the loop? – Ajax1234 Apr 30 '18 at 21:16
  • Its possible, yes, but not that easy. You'd need to call `puts` or something equivalent from the standard library (or issue the syscall yourself, but thats even harder). – tkausl Apr 30 '18 at 21:18
  • Displaying a text in assembly is a bit more complicated, I suggest to do a function which would handle that job. – Nark Apr 30 '18 at 21:19
  • @tkausl I see. I will look into it. Again, thank you. – Ajax1234 Apr 30 '18 at 21:22