Test Driven Development in Assembler a little story about growing software from nothing

Similar documents
64-Bit NASM Notes. Invoking 64-Bit NASM

About the Tutorial. Audience. Prerequisites. Copyright & Disclaimer

Assembly Language Tutorial

For a 64-bit system. I - Presentation Of The Shellcode

Buffer Overflows. Security 2011

Abysssec Research. 1) Advisory information. 2) Vulnerable version

REpsych. : psycholigical warfare in reverse engineering. def con 2015 // domas

Format string exploitation on windows Using Immunity Debugger / Python. By Abysssec Inc

A Tiny Guide to Programming in 32-bit x86 Assembly Language

Hacking Techniques & Intrusion Detection. Ali Al-Shemery arabnix [at] gmail

8. MACROS, Modules, and Mouse

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 20: Stack Frames 7 March 08

Off-by-One exploitation tutorial

Introduction. Figure 1 Schema of DarunGrim2

Lecture 27 C and Assembly

esrever gnireenigne tfosorcim seiranib

Jorix kernel: real-time scheduling

Systems Design & Programming Data Movement Instructions. Intel Assembly

Assembly Language: Function Calls" Jennifer Rexford!

Software Fingerprinting for Automated Malicious Code Analysis

Introduction to Reverse Engineering

Return-oriented programming without returns

Unpacked BCD Arithmetic. BCD (ASCII) Arithmetic. Where and Why is BCD used? From the SQL Server Manual. Packed BCD, ASCII, Unpacked BCD

High-speed image processing algorithms using MMX hardware

CSE-111 Great Ideas in Computer Science Albert Y. C. Chen University at Buffalo, SUNY

TitanMist: Your First Step to Reversing Nirvana TitanMist. mist.reversinglabs.com

Programming from the Ground Up. Jonathan Bartlett

CPU performance monitoring using the Time-Stamp Counter register

Syscall Proxying - Simulating remote execution Maximiliano Caceres <maximiliano.caceres@corest.com> Copyright 2002 CORE SECURITY TECHNOLOGIES

CS61: Systems Programing and Machine Organization

Introduction to MIPS Assembly Programming

How Compilers Work. by Walter Bright. Digital Mars

Introduction to Python

Computer Organization and Assembly Language

X86-64 Architecture Guide

HC12 Assembly Language Programming

Attacking x86 Windows Binaries by Jump Oriented Programming

The Plan Today... System Calls and API's Basics of OS design Virtual Machines

Heap-based Buffer Overflow Vulnerability in Adobe Flash Player

The programming language C. sws1 1

Under The Hood: The System Call

Faculty of Engineering Student Number:

Instruction Set Architecture

Introduction. Application Security. Reasons For Reverse Engineering. This lecture. Java Byte Code

1. General function and functionality of the malware

Stack Overflows. Mitchell Adair

Windows Assembly Programming Tutorial

Fighting malware on your own

CS:APP Chapter 4 Computer Architecture Instruction Set Architecture. CS:APP2e

Character Translation Methods

Programming from the Ground Up

Wrestling with Python Unit testing. Warren Viant

Overview of IA-32 assembly programming. Lars Ailo Bongo University of Tromsø

Programming at Different Levels: A Teaching Module for Undergraduate Computer Architecture Course

Using MMX Instructions to Convert RGB To YUV Color Conversion

Analysis of Win32.Scream

CSC230 Getting Starting in C. Tyler Bletsch

What Happens In Windows 7 Stays In Windows 7

We will learn the Python programming language. Why? Because it is easy to learn and many people write programs in Python so we can share.

TECHNICAL BULLETIN [ 1 / 5 ]

Efficient Cross-Platform Method Dispatching for Interpreted Languages

Intel 8086 architecture

QUIZ-II QUIZ-II. Chapter 5: Control Structures II (Repetition) Objectives. Objectives (cont d.) 20/11/2015. EEE 117 Computer Programming Fall

x64 Cheat Sheet Fall 2015

Compilers. Introduction to Compilers. Lecture 1. Spring term. Mick O Donnell: michael.odonnell@uam.es Alfonso Ortega: alfonso.ortega@uam.

PC Assembly Language. Paul A. Carter

Mike Melanson

Syscall 5. Erik Jonsson School of Engineering and Computer Science. The University of Texas at Dallas

Software Vulnerabilities

W4118 Operating Systems. Junfeng Yang

Using Term to Pierce an Internet Firewall mini HOWTO

Lecture 7: Machine-Level Programming I: Basics Mohamed Zahran (aka Z)

Programming from the Ground Up

Simple C Programs. Goals for this Lecture. Help you learn about:

Compiler Construction

Automatic Network Protocol Analysis

PHP Debugging. Draft: March 19, Christopher Vickery

Stitching the Gadgets On the Ineffectiveness of Coarse-Grained Control-Flow Integrity Protection

How To Hack The Steam Voip On Pc Orchesterian Moonstone 2.5 (Windows) On Pc/Robert Kruber (Windows 2) On Linux (Windows 3.5) On A Pc

Violating Database - Enforced Security Mechanisms

Harnessing Intelligence from Malware Repositories

WLSI Windows Local Shellcode Injection. Cesar Cerrudo Argeniss (

Randy Hyde s Win32 Assembly Language Tutorials (Featuring HOWL) #4: Radio Buttons

Cloud Security Is Not (Just) Virtualization Security

CPSC 226 Lab Nine Fall 2015

Self Protection Techniques in Malware

Using the RDTSC Instruction for Performance Monitoring

Hey, Play Fair! Do you smell that, Kid-Bits? If I had a nose, I d be holding it like this.

PKI, Git and SVN. Adam Young. Presented by. Senior Software Engineer, Red Hat. License Licensed under

Removing Sentinel SuperPro dongle from Applications and details on dongle way of cracking Shub-Nigurrath of ARTeam Version 1.

Computer Organization and Architecture

Chapter 7D The Java Virtual Machine

sys socketcall: Network systems calls on Linux

How To Use A Computer With A Screen On It (For A Powerbook)

TIn 1: Lecture 3: Lernziele. Lecture 3 The Belly of the Architect. Basic internal components of the Pointers and data storage in memory

Bypassing Windows Hardware-enforced Data Execution Prevention

PIC Programming in Assembly. (

Hacking the Preboot execution Environment

Software Development. Intermediate 2. Homework Booklet

Transcription:

Test Driven Development in Assembler a little story about growing software from nothing Olve Maudal During the last decade Test-Driven Development has become an established practice for developing software in the industry. All good programmers must have TDD in the toolbox so that they can use it when appropriate. In this session I will demonstrate Test-Driven Development by example, using nothing but assembler language. A 90 minute session ACCU, Oxford, April 2012

Disclaimer: This is not meant as a tutorial to learn about assembler programming. For example, I am avoiding all/most of the idioms that experienced assembler programmers use (eg, xor to reset a variable, repeat string operations, proper looping, newer and specialized instructions etc). The reason I do this is partly because I am inexperienced with real assembly programming myself, but mostly because it does not add too much value when demonstrating TDD techniques which is the intention of this presentation. Also, I know already that there are some bugs in the code so use with care! If you want to learn about assembler programming on Intel CPU s and BSD based systems I suggest the following sources: http://www.drpaulcarter.com/pcasm/ http://www.int80h.org/ http://pdos.csail.mit.edu/6.858/2011/readings/i386.pdf

LSD *NIX i386 ed, as, ld, make

LSD *NIX i386 ed, as, ld, make

Hello, world!

Hello, world! kernel: int 80h section.data greeting db 'Hello, world!', 0xa section.text global start start: push dword 14 push dword greeting push dword 1 mov eax, 4 call kernel add esp, 12 push dword 0 mov eax, 1 call kernel ; number of characters ; stdout ; sys_write ; same as 3 x pop dword ; exit success value ; sys_exit $ uname -v Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/release_i386 $ nasm -f macho hello.asm $ ld -o hello hello.o $./hello Hello, world! $ echo $? 0 $

Hello, world! kernel: int 80h %define SYS_EXIT 1 %define SYS_READ 3 %define SYS_WRITE 4 %define STDIN 0 %define STDOUT 1 %define STDERR 2 %define EXIT_SUCCESS 0 %define EXIT_FAILURE 1 section.data greeting db 'Hello, world!', 0xa greeting_len equ $-greeting section.text global start start: push dword greeting_len push dword greeting push dword STDOUT mov eax, SYS_WRITE call kernel add esp, 12 push dword EXIT_SUCCESS mov eax, SYS_EXIT call kernel

Hello, world! mylib.inc kernel: int 0x80 %define SYS_EXIT 1 %define SYS_READ 3 %define SYS_WRITE 4 %define STDIN 0 %define STDOUT 1 %define STDERR 2 %define EXIT_SUCCESS 0 %define EXIT_FAILURE 1 hello.asm %include "mylib.inc" section.data greeting db 'Hello, world!', 0xa greeting_len equ $-greeting section.text global start start: sys_write STDOUT, greeting, greeting_len sys_exit EXIT_SUCCESS %macro sys_exit 1 push dword %1 mov eax, SYS_EXIT call kernel %endmacro %macro sys_read 3 push dword %3 push dword %2 push dword %1 mov eax, SYS_READ call kernel add esp, 12 %endmacro %macro sys_write 3 push dword %3 push dword %2 push dword %1 mov eax, SYS_WRITE call kernel add esp, 12 %endmacro

%include "mylib.inc" %define BUFFERSIZE 1024 global start start: section.data.str1 db "What is your name? ".len1 equ $-.str1.str2 db " is invincible!", 0xa.len2 equ $-.str2.buflen dd 0 section.bss.buf resb BUFFERSIZE section.text sys_write STDOUT,.str1,.len1 sys_read STDIN,.buf, BUFFERSIZE cmp eax, 0 jl.exit_with_failure je.exit_with_success mov [.buflen], eax sub [.buflen], dword 1 mov ecx, 10.again: sys_write STDOUT,.buf, [.buflen] sys_write STDOUT,.str2,.len2 dec ecx jnz.again.exit_with_success: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

%include "mylib.inc" %define BUFFERSIZE 1024 global start start: section.data.str1 db "What is your name? ".len1 equ $-.str1.str2 db " is invincible!", 0xa.len2 equ $-.str2.buflen dd 0 section.bss.buf resb BUFFERSIZE section.text sys_write STDOUT,.str1,.len1 sys_read STDIN,.buf, BUFFERSIZE cmp eax, 0 jl.exit_with_failure je.exit_with_success mov [.buflen], eax sub [.buflen], dword 1 mov ecx, 10.again: sys_write STDOUT,.buf, [.buflen] sys_write STDOUT,.str2,.len2 dec ecx jnz.again.exit_with_success: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ nasm -f macho askme.asm

%include "mylib.inc" %define BUFFERSIZE 1024 global start start: section.data.str1 db "What is your name? ".len1 equ $-.str1.str2 db " is invincible!", 0xa.len2 equ $-.str2.buflen dd 0 section.bss.buf resb BUFFERSIZE section.text sys_write STDOUT,.str1,.len1 sys_read STDIN,.buf, BUFFERSIZE cmp eax, 0 jl.exit_with_failure je.exit_with_success mov [.buflen], eax sub [.buflen], dword 1 mov ecx, 10.again: sys_write STDOUT,.buf, [.buflen] sys_write STDOUT,.str2,.len2 dec ecx jnz.again.exit_with_success: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ nasm -f macho askme.asm $ ld askme.o

%include "mylib.inc" %define BUFFERSIZE 1024 global start start: section.data.str1 db "What is your name? ".len1 equ $-.str1.str2 db " is invincible!", 0xa.len2 equ $-.str2.buflen dd 0 section.bss.buf resb BUFFERSIZE section.text sys_write STDOUT,.str1,.len1 sys_read STDIN,.buf, BUFFERSIZE cmp eax, 0 jl.exit_with_failure je.exit_with_success mov [.buflen], eax sub [.buflen], dword 1 mov ecx, 10.again: sys_write STDOUT,.buf, [.buflen] sys_write STDOUT,.str2,.len2 dec ecx jnz.again.exit_with_success: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ nasm -f macho askme.asm $ ld askme.o $./a.out

%include "mylib.inc" %define BUFFERSIZE 1024 global start start: section.data.str1 db "What is your name? ".len1 equ $-.str1.str2 db " is invincible!", 0xa.len2 equ $-.str2.buflen dd 0 section.bss.buf resb BUFFERSIZE section.text sys_write STDOUT,.str1,.len1 sys_read STDIN,.buf, BUFFERSIZE cmp eax, 0 jl.exit_with_failure je.exit_with_success mov [.buflen], eax sub [.buflen], dword 1 mov ecx, 10.again: sys_write STDOUT,.buf, [.buflen] sys_write STDOUT,.str2,.len2 dec ecx jnz.again.exit_with_success: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ nasm -f macho askme.asm $ ld askme.o $./a.out What is your name?

%include "mylib.inc" %define BUFFERSIZE 1024 global start start: section.data.str1 db "What is your name? ".len1 equ $-.str1.str2 db " is invincible!", 0xa.len2 equ $-.str2.buflen dd 0 section.bss.buf resb BUFFERSIZE section.text sys_write STDOUT,.str1,.len1 sys_read STDIN,.buf, BUFFERSIZE cmp eax, 0 jl.exit_with_failure je.exit_with_success mov [.buflen], eax sub [.buflen], dword 1 mov ecx, 10.again: sys_write STDOUT,.buf, [.buflen] sys_write STDOUT,.str2,.len2 dec ecx jnz.again.exit_with_success: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ nasm -f macho askme.asm $ ld askme.o $./a.out What is your name? Larry

%include "mylib.inc" %define BUFFERSIZE 1024 global start start: section.data.str1 db "What is your name? ".len1 equ $-.str1.str2 db " is invincible!", 0xa.len2 equ $-.str2.buflen dd 0 section.bss.buf resb BUFFERSIZE section.text sys_write STDOUT,.str1,.len1 sys_read STDIN,.buf, BUFFERSIZE cmp eax, 0 jl.exit_with_failure je.exit_with_success mov [.buflen], eax sub [.buflen], dword 1 mov ecx, 10.again: sys_write STDOUT,.buf, [.buflen] sys_write STDOUT,.str2,.len2 dec ecx jnz.again.exit_with_success: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ nasm -f macho askme.asm $ ld askme.o $./a.out What is your name? Larry Larry is invincible! Larry is invincible! Larry is invincible! Larry is invincible! Larry is invincible! Larry is invincible! Larry is invincible! Larry is invincible! Larry is invincible! Larry is invincible! $

Monday

Monday Hey, programmer. I got an idea. I need some stuff...

Monday Hey, programmer. I got an idea. I need some stuff... ok?

Monday Hey, programmer. I got an idea. I need some stuff... ok? a program that can calculate the scores in a dice game.

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. ok? which dice game?

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game?

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game? is it yahtzee?

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game? is it yahtzee? yeah, something like that, whatever, original american version? You only need to care about the lower section...you figure it out?

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game? is it yahtzee? yeah, something like that, whatever, original american version? You only need to care about the lower section...you figure it out? I guess so... but what kind of input do I get? And which format of output do you expect? And what is it going to be used for?

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game? is it yahtzee? yeah, something like that, whatever, original american version? You only need to care about the lower section...you figure it out? Input, output, bits and bytes? GEEK! Why ask me? you are the programmer I guess so... but what kind of input do I get? And which format of output do you expect? And what is it going to be used for?

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game? is it yahtzee? yeah, something like that, whatever, original american version? You only need to care about the lower section...you figure it out? Input, output, bits and bytes? GEEK! Why ask me? you are the programmer I guess so... but what kind of input do I get? And which format of output do you expect? And what is it going to be used for? eat flaming death!

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game? is it yahtzee? yeah, something like that, whatever, original american version? You only need to care about the lower section...you figure it out? Input, output, bits and bytes? GEEK! Why ask me? you are the programmer I guess so... but what kind of input do I get? And which format of output do you expect? And what is it going to be used for? eat flaming death! I need it by friday. Right?

Monday Hey, programmer. I got an idea. I need some stuff... a program that can calculate the scores in a dice game. I need it by friday ok? which dice game? is it yahtzee? yeah, something like that, whatever, original american version? You only need to care about the lower section...you figure it out? Input, output, bits and bytes? GEEK! Why ask me? you are the programmer I guess so... but what kind of input do I get? And which format of output do you expect? And what is it going to be used for? eat flaming death! I need it by friday. Right? sure

vague initial requirement Write a library that can score the lower section of a game of yahtzee.

Examples (see also http://en.wikipedia.org/wiki/yahtzee)

yahtzee.asm yahtzee_tests.asm nasm yahtzee.o nasm yahtzee_tests.o ar yahtzee.a ld yahtzee_tests

Makefile all: yahtzee.a check: yahtzee_tests!./yahtzee_tests yahtzee.a: yahtzee.o! ar -rcs $@ $^ yahtzee.o: yahtzee.asm mylib.inc! nasm -f macho $< yahtzee_tests.o: yahtzee_tests.asm mylib.inc! nasm -f macho $< yahtzee_tests: yahtzee_tests.o yahtzee.a! ld -o $@ $^ clean:! rm -f a.out *.o *.a yahtzee_tests

yahtzee_tests.asm

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests bash-3.2$ echo $?

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests bash-3.2$ echo $? 0

yahtzee_tests.asm %include "mylib.inc" global start start: sys_exit EXIT_SUCCESS make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests bash-3.2$ echo $? 0 bash-3.2$

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests make: *** [check] Error 1

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm nasm -f macho yahtzee.asm ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests make: *** [check] Error 1 $

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm Our first unit test failed. This is good! Exactly what we want. The nasm -f macho yahtzee.asm rythm of TDD is : fail, fix, pass... fail, fix, pass ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests make: *** [check] Error 1 $

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm Our first unit test failed. This is good! Exactly what we want. The Fail nasm - Fix - Pass -f macho yahtzee.asm rythm of TDD is : fail, fix, pass... fail, fix, pass ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests make: *** [check] Error 1 $

yahtzee_tests.asm %include "mylib.inc" global start start: mov eax, 6 imul eax, 9 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm Our first unit test failed. This is good! Exactly what we want. The Fail nasm - Fix - Pass -f macho yahtzee.asm rythm of TDD is : fail, fix, pass... fail, fix, pass ar -rcs yahtzee.a yahtzee.o ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests make: *** [check] Error 1 $

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm ld -o yahtzee_tests yahtzee_tests.o yahtzee.a

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE $ make check nasm -f macho yahtzee_tests.asm ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests $

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass $ make check nasm -f macho yahtzee_tests.asm ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests $

yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass $ make check nasm -f macho yahtzee_tests.asm ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests $ All tests are OK!

Let s write a proper unit test yahtzee_tests.asm %include "mylib.inc" global start Fail - Fix - Pass start: mov eax, 6 imul eax, 7 cmp eax, 42 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass $ make check nasm -f macho yahtzee_tests.asm ld -o yahtzee_tests yahtzee_tests.o yahtzee.a./yahtzee_tests $ All tests are OK!

yahtzee_tests.asm %include "mylib.inc" section.text global start start: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" section.text global start start: sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword?? yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword?? what should we urn? yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword?? what should we urn? Remember fail-fix-pass? Return something that you know will fail. yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 0 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 0 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 0 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 Fail - Fix - Pass sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 0 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 Fail - Fix - Pass sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE./yahtzee_tests

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 Fail - Fix - Pass yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE./yahtzee_tests

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 Fail - Fix - Pass yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 Fail - Fix - Pass sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE./yahtzee_tests

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 Fail - Fix - Pass Congratulation. We have completed our first proper fail-fix-pass cycle. Returning 7 is a minimal change to make it pass. This is OK because what we are concerned about now is just to make sure that the wiring of the test is OK. Is the test really being called and is it testing the right function? yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 Fail - Fix - Pass sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE./yahtzee_tests

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 Fail - Fix - Pass Congratulation. We have completed our first proper fail-fix-pass cycle. Returning 7 is a minimal change to make it pass. This is OK because what we are concerned about now is just to make sure that the wiring of the test is OK. Is the test really being called and is it testing the right function? yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 Let s add another unit test. Fail - Fix - Pass section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE./yahtzee_tests

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 Fail - Fix - Pass Congratulation. We have completed our first proper fail-fix-pass cycle. Returning 7 is a minimal change to make it pass. This is OK because what we are concerned about now is just to make sure that the wiring of the test is OK. Is the test really being called and is it testing the right function? yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 Let s add another unit test. Fail - Fix - Pass section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE./yahtzee_tests

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind Should we cheat again and check for the last dice, if section 4 then urn.data 10 otherwise 7? dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: mov eax, dword 7 yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind Should we cheat again and check for the last dice, if section 4 then urn.data 10 otherwise 7? dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 No! Another principle of TDD is that while you are supposed to do simple and naive increments you are section.text not allowed to do obviously stupid stuff. global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass make: *** [check] Error 1

yahtzee.asm yahtzee_tests.asm global score_three_of_a_kind %include "mylib.inc" score_three_of_a_kind: mov eax, dword 7 extern score_three_of_a_kind Should we cheat again and check for the last dice, if section 4 then urn.data 10 otherwise 7? dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 No! Another principle of TDD is that while you are supposed to do simple and naive increments you are section.text not allowed to do obviously stupid stuff. global start start: A simple and naive thing to do here mov is to just esi, sum dice_11122 the and urn the value. That would satisfy call all score_three_of_a_kind the tests and we know the functionality will eventually cmp eax, be needed. dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass make: *** [check] Error 1

yahtzee.asm yahtzee_tests.asm global score_three_of_a_kind %include "mylib.inc" score_three_of_a_kind: mov eax, dword 7 extern score_three_of_a_kind Should we cheat again and check for the last dice, if section 4 then urn.data 10 otherwise 7? dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 No! Another principle of TDD is that while you are supposed to do simple and naive increments you are section.text not allowed to do obviously stupid stuff. global start start: A simple and naive thing to do here mov is to just esi, sum dice_11122 the and urn the value. That would satisfy call all score_three_of_a_kind the tests and we know the functionality will eventually cmp eax, be needed. dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 Fail - Fix - Pass dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm %include "mylib.inc" extern score_three_of_a_kind section.data dice_11122 dd 1,1,1,2,2 dice_11134 Fail - Fix - Pass dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE Fail - Fix - Pass./yahtzee_tests

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE make: *** [check] Error 1

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm global score_three_of_a_kind score_three_of_a_kind: call sum_of_dice sum_of_dice: mov eax, [esi+0] add eax, [esi+4] add eax, [esi+8] add eax, [esi+12] add eax, [esi+16] yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice... yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice... yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice... yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE yahtzee_tests.asm... section.data dice_11122 dd 1,1,1,2,2 dice_11134 dd 1,1,1,3,4 dice_12345 dd 1,2,3,4,5 section.text global start start: mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE count_face: mov yahtzee_tests.asm eax, 0 cmp... ebx, [esi+0] jne.next1 inc section eax.data.next1: dice_11122 dd 1,1,1,2,2 cmp dice_11134 ebx, [esi+4] dd 1,1,1,3,4 jne dice_12345.next2 dd 1,2,3,4,5 inc eax.next2: section.text cmp global ebx, start [esi+8] jne start:.next3 inc eax mov esi, dice_11122.next3: cmp ebx, [esi+12] cmp eax, dword 7 jne.next4 inc eax.next4: mov esi, dice_11134 cmp ebx, [esi+16] jne.next5cmp eax, dword 10 inc eax.next5: mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE./yahtzee_tests count_face: mov yahtzee_tests.asm eax, 0 cmp... ebx, [esi+0] jne.next1 inc section eax.data.next1: dice_11122 dd 1,1,1,2,2 cmp dice_11134 ebx, [esi+4] dd 1,1,1,3,4 jne dice_12345.next2 dd 1,2,3,4,5 inc eax.next2: section.text cmp global ebx, start [esi+8] jne start:.next3 inc eax mov esi, dice_11122.next3: cmp ebx, [esi+12] cmp eax, dword 7 jne.next4 inc eax.next4: mov esi, dice_11134 cmp ebx, [esi+16] jne.next5cmp eax, dword 10 inc eax.next5: mov esi, dice_12345 cmp eax, dword 0 sys_exit EXIT_SUCCESS.exit_with_failure: sys_exit EXIT_FAILURE

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 Looking good! Looking good! cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 Looking good! Looking good! cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20./yahtzee_tests...

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20... mov esi, dice_61666 cmp eax, dword 18+7

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20 make: *** [check] Error 1... mov esi, dice_61666 cmp eax, dword 18+7

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20 make: *** [check] Error 1... mov esi, dice_61666 cmp eax, dword 18+7

yahtzee_tests.asm... mov esi, dice_11122 cmp eax, dword 7 mov esi, dice_11134 cmp eax, dword 10 mov esi, dice_12345 cmp eax, dword 0 mov esi, dice_53552 cmp eax, dword 20 mov esi, dice_11666 cmp eax, dword 20 Oh no... what happened? make: *** [check] Error 1... mov esi, dice_61666 cmp eax, dword 18+7

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE count_face: mov eax, 0 cmp ebx, [esi+0] jne.next1 inc eax.next1: cmp ebx, [esi+4] jne.next2 inc eax.next2: cmp ebx, [esi+8] jne.next3 inc eax.next3: cmp ebx, [esi+12] jne.next4 inc eax.next4: cmp ebx, [esi+16] jne.next5 inc eax.next5:

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE count_face: mov eax, 0 cmp ebx, [esi+0] jne.next1 inc eax.next1: cmp ebx, [esi+4] jne.next2 inc eax.next2: cmp ebx, [esi+8] jne.next3 inc eax.next3: cmp ebx, [esi+12] jne.next4 inc eax.next4: cmp ebx, [esi+16] jne.next5 inc eax.next5:

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE count_face: mov eax, 0 cmp ebx, [esi+0] jne.next1 inc eax.next1: cmp ebx, [esi+4] jne.next2 inc eax.next2: cmp ebx, [esi+8] jne.next3 inc eax.next3: cmp ebx, [esi+12] jne.next4 inc eax.next4: cmp ebx, [esi+16] jne.next5 inc eax.next5: But of course...

yahtzee.asm %define TRUE 1 %define FALSE 0 global score_three_of_a_kind score_three_of_a_kind: call have_3_of_a_kind cmp eax, TRUE je.urn_sum.urn_zero: mov eax, 0.urn_sum: call sum_of_dice have_3_of_a_kind: mov ebx, 1 ; face value.check_next_face_value: call count_face cmp eax, 3 je.urn_true inc ebx cmp ebx, 6 jg.urn_false jmp.check_next_face_value.urn_false: mov eax, FALSE.urn_true: mov eax, TRUE count_face: mov eax, 0 cmp ebx, [esi+0] jne.next1 inc eax.next1: cmp ebx, [esi+4] jne.next2 inc eax.next2: cmp ebx, [esi+8] jne.next3 inc eax.next3: cmp ebx, [esi+12] jne.next4 inc eax.next4: cmp ebx, [esi+16] jne.next5 inc eax.next5: But of course...