Except for COBOL perhaps... just kidding, it's true, in Assembly, "Hello World" requires you to do some actual work, whereas for higher languages, it usually serves to give a first feel of the new language.
Hi, just wanted to add to the many thank you's here. Sincerely, thank you. Im studying CS and taking an Assembly course. The professor has geared the course towards windows and Linux and x86_64 based machines and I have been left on my own to figure out ARM64 architecture. Your video just helped me get my stuff together. I have been trying for a week and my assignment is due tomorrow. THANK YOU SO MUCH!!!
Thank you so much for doing these videos! I am in a CPU architecture course learning ARM assembly on a raspberry pi, I’ve been really hoping to move what I’ve been learning on the pi, to the M1. I have really been struggling finding resources that have allowed me to make any progress. YOUR VIDEOS ARE EXACTLY WHAT IVE BEEN LOOKING FOR! Immediately subscribed! I can’t wait to see where this channel goes!
Hello! In 46:38 you say that X0 is written into the lower order byte of the stack. Since apple silicon is little-endian, this means that X0 is written into the "first" byte of the two-byte stack alignment? This is a bit confusing to me because the stack grows "downward", so what would be the lower order byte of it, a lower, or higher address?
I hope this will clarify your issue: (1) Each stack entry consists of 128 bits, which we can think of as 2 chunks of 64 bits. If the Stack Pointer currently points to address A (top of the stack), then writing something onto the stack will fill up the bytes at addresses A, A+1, A+2, ... , A+15. Just to be clear: In the image in the video I assume that the lower addresses _within_ a stack entry start on the left. (2) The growing of the stack (towards lower addresses) refers to the initial addresses of the stack entries, which by (1) are 128 bits apart. For example, if the current top of the stack is at address A, then pushing something onto the stack will make the Stack Pointer point to address A-16, which is reflected in the parameter #-16! in the STR instruction. (Check: This new stack top includes addresses (A-16), (A-16)+1, ... , (A-16)+15, so that it stops precisely at the address A, which is the beginning address of our previous stack top.) (3) The register X0 is 64 bits (8 bytes) in size, so it will occupy half of a stack entry. The STR instruction as stated in the video will store X0 at the current address A of the Stack Pointer, which points to the lowest address of the current stack top. So the 8 bytes that make up X0 will be written to the bytes at A, A+1, A+2, ... , A+7 on the stack. These are what I call the "lower order bytes" of the stack. Strictly speaking, this does not depend on a little-endian or big-endian convention, since the operations involved do not in any way depend on that. It would be the responsibility of the programmer to make sure the data is stored in the register in the correct manner and the pushed to the stack in the correct order.
2 місяці тому
@@hackvlix Thank you so much for the very detailed explanation. Now I think I've got it! Thanks!
Thanks for the video! I recommend using audacity to remove background noises from the video, it can help improve the overall quality and it's pretty simple to use.
Glad you like it. I've had some familiarity with Intel assembly for quite some time, so it's hard to say exactly where I learned it. There are a few differences between Intel and ARM, but they a rather easy to understand if you already know one of the two. As for ARM assembly, I mostly learned it from the book in my first reference, and the link in the second reference contains the details to apply it to macOS. The technical minutiae such as the bitwise encoding of the ARM instructions can be found in the Arm Architecture Reference Manual (third reference above).
Great tutorial on ARM64, one of the best on UA-cam. Thank you for sharing it with us! However, I have to say, for a reduced instruction set, ARM64 instruction set seems quite confusing to me. Sometimes it makes simple things quite complex. Sometimes it lacks some consistency on its syntax. I mean, it is common to have analogous operations with very different syntax sometimes. In the end, "reduced" does not mean easier nor simpler ¯\_(ツ)_/¯
M1: ARMv8.5-A M2, M3: ARMv8.6-A You can find these in the LLVM source code (search for "apple" or whatever chip you are looking for): github.com/llvm/llvm-project/blob/main/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@hackvlix Thanks. Do you know what are the general purpose registers that can be safely used by the user in ARMv8.5/6-A. I read somewhere that they were X0-X30, but then I read somewhere else that X18 should not be touched, and that X8 serves a specific purpose. which one is true?
@@younesmdarhrialaoui643 Some remarks at 6:18 in the video. A nice overview is given in this graphic: documentation-service.arm.com/static/5fbd26f271eff94ef49c7018
@@hackvlix Thank you very much, you're amazing. Here is something I don't understand though: They call the X0-X30 general purpose registers meaning they can be used for anything the user wants them to be used for. But the weird thing is that some of these registers shouldn't be touched like X18, or X29 (the frame pointer). If I store a value in X29 and do some math it will have different consequences then if I did it on an "actual" gp register. Can you explain to me this confusion?
@@younesmdarhrialaoui643 No, using X29 for some operations will not have different consequences than using any "normal" register. But the problem is that by overwriting X29 you might mess up the stack frame and cause a crash when a program tries to unwind the stack with the overwritten frame pointer, that's why it's better to not use it. As for X18, I do not know what Apple has reserved this for, but it is suggested not to use it.
very clear tutorial. I tried playing around with the return function btw to use it as a jump. If you guess how you are very clever. ``` .text .global _start .align 4 _start: adr x30, _start ret ```
Hm, this is a bit puzzling for me. This error occurs when the assembler cannot resolve the address of a label. Just to check - you have used the "as" and "ld" commands as described in the video? Could it be that you put the label "helloworld" in the ".data" section? In that case, the ADR instruction as used here would not find it.
@@brook1598 For longer code, it is probably better to use the .data segment. The ADRP instruction makes it possible to defer address resolution to the linker if the assembler cannot resolve the address. This is actually an interesting addition to the video.
@@hackvlix Ahhh okay interesting, this is my first time learning any assembly and it's been super interesting. Apart from using these awesome videos you've produced here would you say that "Programming with 64-bit ARM Assembly Language" with the additional "Hello Silicon" repo is enough to get me started? Would you recommend any other resources in addition to the ones in the description? I just want to thank you for making these videos, these are super helpful and in a format that is interesting and visually appealing, especially with the examples you give. Keep up the great work!
Thank you! Would love to see more (total) beginner Assembly for Silicon videos!
Writing assembly and printing "Hello world" is more exciting than any Hello World in any other language. Is it just me?
Except for COBOL perhaps... just kidding, it's true, in Assembly, "Hello World" requires you to do some actual work, whereas for higher languages, it usually serves to give a first feel of the new language.
This video/series is the GOAT. Thanks for this gem
Glad you like it :)
Hi, just wanted to add to the many thank you's here. Sincerely, thank you. Im studying CS and taking an Assembly course. The professor has geared the course towards windows and Linux and x86_64 based machines and I have been left on my own to figure out ARM64 architecture. Your video just helped me get my stuff together. I have been trying for a week and my assignment is due tomorrow. THANK YOU SO MUCH!!!
Great to hear! 😀 Good luck with your studies!
Thank you so much for doing these videos! I am in a CPU architecture course learning ARM assembly on a raspberry pi, I’ve been really hoping to move what I’ve been learning on the pi, to the M1. I have really been struggling finding resources that have allowed me to make any progress. YOUR VIDEOS ARE EXACTLY WHAT IVE BEEN LOOKING FOR! Immediately subscribed! I can’t wait to see where this channel goes!
Oh, first comment on the channel ever. 😀 Thanks a lot, I'm glad you liked it.
Thanks! Found this video while looking to program in ARM assembly on my new Mac and this helped a lot!
Thank you very much for such a clear and complete explanation! This is exactly what I've been looking for!
Thanks, I'm happy it helps.
Thanks a lot! Clear and concise..also very good teaching 😁
Fantastic explanation and very useful material. Thank you.
Thanks, glad you like it!
Hello! In 46:38 you say that X0 is written into the lower order byte of the stack. Since apple silicon is little-endian, this means that X0 is written into the "first" byte of the two-byte stack alignment? This is a bit confusing to me because the stack grows "downward", so what would be the lower order byte of it, a lower, or higher address?
I hope this will clarify your issue:
(1) Each stack entry consists of 128 bits, which we can think of as 2 chunks of 64 bits.
If the Stack Pointer currently points to address A (top of the stack), then writing something onto the stack will fill up the bytes at addresses A, A+1, A+2, ... , A+15.
Just to be clear: In the image in the video I assume that the lower addresses _within_ a stack entry start on the left.
(2) The growing of the stack (towards lower addresses) refers to the initial addresses of the stack entries, which by (1) are 128 bits apart. For example, if the current top of the stack is at address A, then pushing something onto the stack will make the Stack Pointer point to address A-16, which is reflected in the parameter #-16! in the STR instruction.
(Check: This new stack top includes addresses (A-16), (A-16)+1, ... , (A-16)+15, so that it stops precisely at the address A, which is the beginning address of our previous stack top.)
(3) The register X0 is 64 bits (8 bytes) in size, so it will occupy half of a stack entry. The STR instruction as stated in the video will store X0 at the current address A of the Stack Pointer, which points to the lowest address of the current stack top. So the 8 bytes that make up X0 will be written to the bytes at A, A+1, A+2, ... , A+7 on the stack.
These are what I call the "lower order bytes" of the stack.
Strictly speaking, this does not depend on a little-endian or big-endian convention, since the operations involved do not in any way depend on that. It would be the responsibility of the programmer to make sure the data is stored in the register in the correct manner and the pushed to the stack in the correct order.
@@hackvlix Thank you so much for the very detailed explanation. Now I think I've got it! Thanks!
Thank you very much for this high-quality videos - einfach genial! ♥️
You're welcome. Glad you like it.
Great content. You are a great teacher!
Thanks! Glad you like it.
Thanks for the video!
I recommend using audacity to remove background noises from the video,
it can help improve the overall quality and it's pretty simple to use.
Thanks! I will try out Audacity.
Where did you learn all of this? This content is amazing
Glad you like it. I've had some familiarity with Intel assembly for quite some time, so it's hard to say exactly where I learned it. There are a few differences between Intel and ARM, but they a rather easy to understand if you already know one of the two.
As for ARM assembly, I mostly learned it from the book in my first reference, and the link in the second reference contains the details to apply it to macOS. The technical minutiae such as the bitwise encoding of the ARM instructions can be found in the Arm Architecture Reference Manual (third reference above).
Thank you so much for videos
Thanks for watching, glad you liked it.
Great tutorial on ARM64, one of the best on UA-cam. Thank you for sharing it with us! However, I have to say, for a reduced instruction set, ARM64 instruction set seems quite confusing to me. Sometimes it makes simple things quite complex. Sometimes it lacks some consistency on its syntax. I mean, it is common to have analogous operations with very different syntax sometimes. In the end, "reduced" does not mean easier nor simpler ¯\_(ツ)_/¯
Glad that you like it... and, yes, RISC definitely does not mean reduced complexity for the programmer.
Thanks very much!
Glad you like it!
thank you 😊
Amazing content, thx
I get the "ld: library not found for -lSystem" error on my m1. Do you have any idea why? (I have xcode installed)
Sorry, I don't really know what the issue is.
What path do you get when you run xcrun -sdk macosx --show-sdk-path ?
What's the name of the instruction set Apple uses on their chip?
M1: ARMv8.5-A
M2, M3: ARMv8.6-A
You can find these in the LLVM source code (search for "apple" or whatever chip you are looking for):
github.com/llvm/llvm-project/blob/main/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@hackvlix Thanks. Do you know what are the general purpose registers that can be safely used by the user in ARMv8.5/6-A. I read somewhere that they were X0-X30, but then I read somewhere else that X18 should not be touched, and that X8 serves a specific purpose. which one is true?
@@younesmdarhrialaoui643 Some remarks at 6:18 in the video. A nice overview is given in this graphic: documentation-service.arm.com/static/5fbd26f271eff94ef49c7018
@@hackvlix Thank you very much, you're amazing.
Here is something I don't understand though: They call the X0-X30 general purpose registers meaning they can be used for anything the user wants them to be used for. But the weird thing is that some of these registers shouldn't be touched like X18, or X29 (the frame pointer). If I store a value in X29 and do some math it will have different consequences then if I did it on an "actual" gp register. Can you explain to me this confusion?
@@younesmdarhrialaoui643 No, using X29 for some operations will not have different consequences than using any "normal" register. But the problem is that by overwriting X29 you might mess up the stack frame and cause a crash when a program tries to unwind the stack with the overwritten frame pointer, that's why it's better to not use it. As for X18, I do not know what Apple has reserved this for, but it is suggested not to use it.
Lmao sa
You literally stole your octopus image from the book Other Minds.
Peter Godfrey-Smith owns the copyright for that image.
Haha, nope. The octopus is from Ernst Haeckel's book "Kunstformen der Natur" (1904). It is not copyrighted.
r/confidentlywrong
very clear tutorial. I tried playing around with the return function btw to use it as a jump. If you guess how you are very clever.
```
.text
.global _start
.align 4
_start:
adr x30, _start
ret
```
Hey man, I seem to be getting this issue, any thoughts?
error: unknown AArch64 fixup kind!
adr x1, helloworld
Hm, this is a bit puzzling for me.
This error occurs when the assembler cannot resolve the address of a label. Just to check - you have used the "as" and "ld" commands as described in the video?
Could it be that you put the label "helloworld" in the ".data" section? In that case, the ADR instruction as used here would not find it.
@@hackvlix, this seems to have fixed the error for some reason haha
adrp x1, helloworld@PAGE
add x1, x1, helloworld@PAGEOFF
@@hackvlix And yeah, seems I put .text and .data labels in my code, whoops
@@brook1598 For longer code, it is probably better to use the .data segment. The ADRP instruction makes it possible to defer address resolution to the linker if the assembler cannot resolve the address.
This is actually an interesting addition to the video.
@@hackvlix Ahhh okay interesting, this is my first time learning any assembly and it's been super interesting. Apart from using these awesome videos you've produced here would you say that "Programming with 64-bit ARM Assembly Language" with the additional "Hello Silicon" repo is enough to get me started? Would you recommend any other resources in addition to the ones in the description? I just want to thank you for making these videos, these are super helpful and in a format that is interesting and visually appealing, especially with the examples you give. Keep up the great work!