From: Nuxxie Subject: Programming Lesson 2 Newsgroups: comp.os.linux.advocacy User-Agent: Pan/0.146 (Hic habitat felicitas; d7a48b4 gitlab.gnome.org/GNOME/pan.git) Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lines: 69 Path: ...!weretis.net!feeder6.news.weretis.net!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!feeder.usenetexpress.com!tr2.iad1.usenetexpress.com!news.usenetexpress.com!not-for-mail Date: Thu, 21 Mar 2024 12:10:33 +0000 Nntp-Posting-Date: Thu, 21 Mar 2024 12:10:33 +0000 X-Received-Bytes: 2919 X-Complaints-To: abuse@usenetexpress.com Organization: UsenetExpress - www.usenetexpress.com Message-Id: <17bec662176ed584$4174$3384359$802601b3@news.usenetexpress.com> Bytes: 3315 Don't listen to those incompetent chuckleheads. To program, one must first know hardware. All programming can be reduced to SEQUENCE and BRANCHING. That's it. There is nothing more. The x64 CPU has a register known as the RIP, or instruction pointer, which contains the memory address of the next instruction. The x64 CPU reads the instruction bytes from the address in the RIP, executes the instruction, and then increments the RIP by the appropriate amount so that it points to the next instruction. The RIP, like all x64 regs, is 64-bits in width. This gives 2^64 bytes of addressable memory (although this is physically limited to less). This is sequencing. What about branching? Branching is accomplished by "jump" instructions, which are either absolute or conditional. In a jump, the CPU loads the address specified in the jump insruction into the RIP. The sequence continues from the jump address: JMP 0x5698f7c6e38fccff Sequence continues at the memory address 0x5698f7c6e38fccff. This is an absolute jump, but jumps can be conditional: JZ $address This indicates to jump if the zero condition flag has been set. In the x64 CPU there is a 16-bit Status Register (SR). Each of the bits in the SR represents a condition flag. After the execution of an instruction, certain status bits can be set (= 1) or unset (= 0). For example, if the result of a logical or arithmetic operation is zero the the zero status bit is set. Subsequent instructions can use this info to make decisions, such as whether or not to jump. DEC eax ;decrement the eax register JNZ $loop ;jump to $loop address if the result is not zero Neat and simple. In addition to absolute and conditional jumps there is the "jump to subroutine," a.k.a. the "CALL" instrucion. CALL $address The CALL instruction causes the CPU to push the RIP, which contains the address of the following instruction, onto the stack and then jump to $address. When a RET instruction is encountered in the new sequence, the RIP is popped from the stack and the sequence returns to the place where it jumped from. That's it. That is how the x86 CPU effects sequence and branching. It's very, very simple. End of lesson. Now just get an assembler and start to fuck around making various jumps. You'll soon get the hang of it. Remember: the best philosophy of programming is to fuck all that abstract shit and get close to the machine.