How to use imm32 method of x86 Package

Best Syzkaller code snippet using x86.imm32

go.go

Source:go.go Github

copy

Full Screen

1package main2import (3 "os"4 "fmt"5 "strings"6 "strconv"7 "unicode"8 "go/ast"9 "go/token"10 "go/parser"11 "go/typechecker"12 "github.com/droundy/go/elf"13 "github.com/droundy/go/x86"14 "github.com/droundy/goopt"15)16var myfiles = token.NewFileSet()17type StringVisitor CompileVisitor18func (v StringVisitor) Visit(n0 ast.Node) (w ast.Visitor) {19 //fmt.Printf("in StringVisitor, n0 is %s of type %T\n", n0, n0)20 if n,ok := n0.(*ast.BasicLit); ok && n != nil && n.Kind == token.STRING {21 str,err := strconv.Unquote(string(n.Value))22 if err != nil {23 panic(err)24 }25 sanitize := func(rune int) int {26 if unicode.IsLetter(rune) {27 return rune28 }29 return -130 }31 fmt.Println("string literals are: ", v.string_literals)32 if _,ok := v.string_literals[str]; !ok {33 strname := "string_" + strings.Map(sanitize, str)34 for {35 // See if our strname is valid...36 nameexists := false37 for _,n := range v.string_literals {38 if n == strname {39 nameexists = true40 }41 }42 if !nameexists {43 break // we've got a unique name already!44 }45 strname = strname + "X"46 }47 *v.assembly = append(*v.assembly,48 x86.Symbol(strname),49 x86.Commented(x86.Ascii(str), "a non-null-terminated string"))50 v.string_literals[str] = strname51 fmt.Println("Got new string literal: ", str)52 }53 }54 return v55}56type CompileVisitor struct {57 assembly *[]x86.X8658 string_literals map[string]string59 Stack *Stack60}61func (v *CompileVisitor) Append(xs... x86.X86) {62 *v.assembly = append(*v.assembly, xs...)63}64func (v *CompileVisitor) FunctionPrologue(fn *ast.FuncDecl) {65 v.Stack = v.Stack.New(fn.Name.Name)66 ftype := ast.NewType(ast.Function)67 ftype.N = uint(fn.Type.Results.NumFields())68 ftype.Params = ast.NewScope(nil)69 fmt.Println("Working on function", fn.Name.Name)70 if fn.Type.Results != nil {71 resultnum := 072 for _,resultfield := range fn.Type.Results.List {73 names := []string{"_"}74 if resultfield.Names != nil {75 names = []string{}76 for _,i := range resultfield.Names {77 names = append(names, i.Name)78 }79 }80 t := TypeExpression(resultfield.Type)81 for _,n := range names {82 ftype.Params.Insert(&ast.Object{ ast.Fun, n, t, resultfield, 0 })83 resultnum++84 v.Stack.DefineVariable(n, t, fmt.Sprintf("return_value_%d", resultnum))85 // The return values are actually allocated elsewhere... here86 // we just need to define the function type properly so it87 // gets called properly.88 }89 }90 }91 fmt.Println("Stack size after results is", v.Stack.Size)92 v.Stack.ReturnSize = v.Stack.Size93 // The arguments are pushed last argument first, so that eventually94 // the types of the "later" arguments can depend on the first95 // arguments, which seems nice to me.96 for pi:=len(fn.Type.Params.List)-1; pi>=0; pi-- {97 paramfield := fn.Type.Params.List[pi]98 names := []string{"_"}99 if paramfield.Names != nil {100 names = []string{}101 for _,i := range paramfield.Names {102 names = append(names, i.Name)103 }104 }105 t := TypeExpression(paramfield.Type)106 for i:=len(names)-1; i>=0; i-- {107 n := names[i]108 ftype.Params.Insert(&ast.Object{ ast.Fun, n, t, paramfield, 0 })109 v.Stack.DefineVariable(n, t)110 // The function parameters are actually allocated111 // elsewhere... here we just need to define the function type112 // properly so it gets called properly.113 }114 }115 fmt.Println("Stack size after params is", v.Stack.Size)116 v.Stack.DefineVariable("return", IntType)117 fmt.Println("Stack size after return is", v.Stack.Size)118 v.Stack = v.Stack.New("_")119 DefineGlobal(fn.Name.Name, ftype)120 // symbol for the start name121 pos := myfiles.Position(fn.Pos())122 v.Append(x86.Commented(x86.GlobalSymbol("main_"+fn.Name.Name),123 fmt.Sprint(pos.Filename, ": line ", pos.Line)))124 // If we had arguments, we'd want to swap them with the return125 // address here...126}127func (v *CompileVisitor) FunctionPostlogue() {128 // First we roll back the stack from where we started...129 for v.Stack.Name == "_" {130 // We need to pop off any extra layers of stack we've added...131 if v.Stack.Size > 0 {132 v.Append(x86.Commented(x86.AddL(x86.Imm32(v.Stack.Size), x86.ESP),133 "We stored this much on the stack so far."))134 }135 v.Stack = v.Stack.Parent // We've popped off the arguments...136 }137 // Now jump to the "real" postlogue. This is a little stupid, but I138 // expect it'll come in handy when I implement defer (not to mention139 // panic/recover).140 v.Append(x86.Jmp(x86.Symbol("return_" + v.Stack.Name)))141}142func (v *CompileVisitor) Visit(n0 ast.Node) (w ast.Visitor) {143 // The following only handles functions (not methods)144 if n,ok := n0.(*ast.FuncDecl); ok && n.Recv == nil {145 v.FunctionPrologue(n)146 for _,statement := range n.Body.List {147 v.CompileStatement(statement)148 }149 v.FunctionPostlogue()150 v.Append(x86.GlobalSymbol("return_"+n.Name.Name))151 v.Append(x86.Commented(x86.PopL(x86.EAX), "Pop the return address"))152 // Pop off function arguments...153 fmt.Println("Function", v.Stack.Name, "has stack size", v.Stack.Size)154 fmt.Println("Function", v.Stack.Name, "has return values size", v.Stack.ReturnSize)155 v.Append(x86.Commented(x86.AddL(x86.Imm32(v.Stack.Size - 4 - v.Stack.ReturnSize), x86.ESP),156 "Popping "+v.Stack.Name+" arguments."))157 // Then we return!158 v.Append(x86.RawAssembly("\tjmp *%eax"))159 v.Stack = v.Stack.Parent160 return nil // No need to peek inside the func declaration!161 }162 return v163}164func (v *CompileVisitor) PopType(t ast.Type) {165 switch t.Form {166 case ast.Tuple:167 for _,o := range t.Params.Objects {168 v.PopType(*o.Type)169 }170 case ast.Basic:171 switch t.N {172 case ast.String:173 v.Append(x86.AddL(x86.Imm32(8), x86.ESP))174 default:175 panic(fmt.Sprintf("I don't know how to pop basic type %s", t))176 }177 default:178 panic(fmt.Sprintf("I don't know how to pop type %s", t.Form))179 }180}181func (v *CompileVisitor) CompileStatement(statement ast.Stmt) {182 switch s := statement.(type) {183 case *ast.EmptyStmt:184 // It is empty, I can handle that!185 case *ast.ExprStmt:186 v.CompileExpression(s.X)187 t := ExprType(s.X, v.Stack)188 switch t.Form {189 case ast.Tuple:190 191 }192 case *ast.ReturnStmt:193 for resultnum,e := range s.Results {194 vname := fmt.Sprintf("return_value_%d", resultnum+1)195 v.CompileExpression(e)196 v.PopTo(vname)197 }198 v.FunctionPostlogue()199 default:200 panic(fmt.Sprintf("I can't handle statements such as: %T", statement))201 }202}203func (v *CompileVisitor) CompileExpression(exp ast.Expr) {204 switch e := exp.(type) {205 case *ast.BasicLit:206 switch e.Kind {207 case token.STRING:208 str,err := strconv.Unquote(string(e.Value))209 if err != nil {210 panic(err)211 }212 n,ok := v.string_literals[str]213 if !ok {214 panic(fmt.Sprintf("I don't recognize the string: %s", string(e.Value)))215 }216 v.Append(217 x86.Commented(x86.PushL(x86.Symbol(n)), "Pushing string literal "+string(e.Value)),218 x86.PushL(x86.Imm32(len(str))))219 v.Stack.Push(StringType) // let the stack know we've pushed a literal220 default:221 panic(fmt.Sprintf("I don't know how to deal with literal: %s", e))222 }223 case *ast.CallExpr:224 if fn,ok := e.Fun.(*ast.Ident); ok {225 pos := myfiles.Position(fn.Pos())226 switch fn.Name {227 case "println", "print":228 if len(e.Args) != 1 {229 panic(fmt.Sprintf("%s expects just one argument, not %d", fn.Name, len(e.Args)))230 }231 argtype := ExprType(e.Args[0], v.Stack)232 if argtype.N != ast.String || argtype.Form != ast.Basic {233 panic(fmt.Sprintf("Argument to %s has type %s but should have type string!",234 fn.Name, argtype))235 }236 v.Stack = v.Stack.New("arguments")237 v.CompileExpression(e.Args[0])238 v.Append(x86.Commented(x86.Call(x86.Symbol(fn.Name)),239 fmt.Sprint(pos.Filename, ": line ", pos.Line)))240 v.Stack = v.Stack.Parent // A hack to let the callee clean up arguments241 default:242 // This must not be a built-in function...243 functype := v.Stack.Lookup(fn.Name)244 if functype.Type().Form != ast.Function {245 panic("Function "+ fn.Name + " is not actually a function!")246 }247 for i:=0; i<int(functype.Type().N); i++ {248 // Put zeros on the stack for the return values (and define these things)249 v.Declare(functype.Type().Params.Objects[i].Name,250 functype.Type().Params.Objects[i].Type)251 }252 v.Stack = v.Stack.New("arguments")253 for i:=len(e.Args)-1; i>=0; i-- {254 v.CompileExpression(e.Args[i])255 }256 // FIXME: I assume here that there is no return value!257 v.Append(x86.Commented(x86.Call(x86.Symbol("main_"+fn.Name)),258 fmt.Sprint(pos.Filename, ": line ", pos.Line)))259 v.Stack = v.Stack.Parent // A hack to let the callee clean up arguments260 }261 } else {262 panic(fmt.Sprintf("I don't know how to deal with complicated function: %s", e.Fun))263 }264 case *ast.Ident:265 evar := v.Stack.Lookup(e.Name)266 switch SizeOnStack(evar.Type()) {267 case 4:268 v.Append(x86.Commented(x86.MovL(evar.InMemory(), x86.EAX), "Reading variable "+e.Name))269 v.Append(x86.PushL(x86.EAX))270 v.Stack.DefineVariable("_copy_of_"+e.Name, evar.Type())271 case 8:272 v.Append(x86.Comment(fmt.Sprintf("The offset of %s is %s", e.Name, evar.InMemory())))273 v.Append(x86.Commented(x86.MovL(evar.InMemory().Add(4), x86.EAX),274 "Reading variable "+e.Name))275 v.Append(x86.MovL(evar.InMemory(), x86.EBX))276 v.Append(x86.PushL(x86.EAX))277 v.Append(x86.PushL(x86.EBX))278 v.Stack.DefineVariable("_copy_of_"+e.Name, evar.Type())279 default:280 panic(fmt.Sprintf("I don't handle variables with length %s", SizeOnStack(evar.Type())))281 }282 default:283 panic(fmt.Sprintf("I can't handle expressions such as: %T value %s", exp, exp))284 }285}286func (v *CompileVisitor) PopTo(vname string) {287 v.Append(v.Stack.PopTo(vname))288}289func (v *CompileVisitor) Declare(vname string, t *ast.Type) {290 switch SizeOnStack(t) {291 case 4:292 v.Append(x86.Commented(x86.PushL(x86.Imm32(0)), "This is variable "+vname))293 case 8:294 v.Append(x86.Commented(x86.PushL(x86.Imm32(0)), "This is variable "+vname))295 v.Append(x86.Commented(x86.PushL(x86.Imm32(0)), "This is variable "+vname))296 default:297 panic(fmt.Sprintf("I don't handle variables with length %s", SizeOnStack(t)))298 }299 v.Stack.DefineVariable(vname, t)300}301func main() {302 goopt.Parse(func() []string { return nil })303 if len(goopt.Args) > 0 {304 x,err := parser.ParseFiles(myfiles, goopt.Args, 0)305 die(err)306 fmt.Fprintln(os.Stderr, "Parsed: ", *x["main"])307 die(typechecker.CheckPackage(myfiles, x["main"], nil))308 fmt.Fprintln(os.Stderr, "Checked: ", *x["main"])309 //for _,a := range x["main"].Files {310 // die(printer.Fprint(os.Stdout, a))311 //}312 aaa := x86.StartData313 var bbb *Stack314 var cv = CompileVisitor{ &aaa, make(map[string]string), bbb.New("global")}315 ast.Walk(StringVisitor(cv), x["main"])316 cv.Append(x86.StartText...)317 ast.Walk(&cv, x["main"])318 // Here we just add a crude debug library319 cv.Append(x86.Debugging...)320 ass := x86.Assembly(*cv.assembly)321 //fmt.Println(ass)322 die(elf.AssembleAndLink(goopt.Args[0][:len(goopt.Args[0])-3], []byte(ass)))323 }324}325func die(err os.Error) {326 if err != nil {327 fmt.Fprintln(os.Stderr, err)328 os.Exit(1)329 }330}...

Full Screen

Full Screen

x86.go

Source:x86.go Github

copy

Full Screen

1package x862import (3 "fmt"4)5func Assembly(code []X86) (out string) {6 // FIXME: This is stupidly O(N^2)...7 for _,a := range code {8 out += a.X86() + "\n"9 }10 return11}12// An Assembly is something that can be converted into a line of13// assembly language.14type X86 interface {15 X86() string16}17// a W32 is a source (or sink) for a double-word (which I think of as18// a word, but x86 assembly doesn't), which could either be a register19// or a memory location.20type W32 interface {21 W32() string22}23// a W16 is a source (or sink) for a word (which I think of as a24// short, but x86 assembly doesn't), which could either be a register25// or a memory location.26type W16 interface {27 W16() string28}29// a W8 is a source (or sink) for a byte, which could either be a30// register or a memory location.31type W8 interface {32 W8() string33}34type Ptr interface {35 Ptr() string36}37// And now we come to the concrete types.38// A Comment is the most boring part of assembly, but pretty useful39// for trying to understand generated code.40type commentType struct {41 instr X8642 c string43}44func (s commentType) X86() string {45 if c,ok := s.instr.(commentType); ok {46 return "\n# " + c.c + "\n"47 }48 return s.instr.X86() + "\t# " + s.c49}50func Comment(x string) X86 {51 return commentType{commentType{Symbol(""), x}, ""}52}53func Commented(instr X86, x string) X86 {54 return commentType{instr, x}55}56// A Symbol marks a location in the binary source file, which could be57// a function or a global variable or even a global constant.58type Symbol string59func (s Symbol) X86() string {60 return string(s) + ":"61}62func (s Symbol) W8() string {63 return "$" + string(s)64}65func (s Symbol) W16() string {66 return "$" + string(s)67}68func (s Symbol) W32() string {69 return "$" + string(s)70}71func (s Symbol) Ptr() string {72 return string(s)73}74// Memory is an in-memory reference75type Memory struct {76 Disp Ptr77 Base W3278 Index W3279 Scale Ptr80}81func (m Memory) W32() string {82 offstr := ""83 if m.Disp != nil {84 offstr = m.Disp.Ptr()85 }86 bstr := ""87 if m.Base != nil {88 bstr = m.Base.W32()89 }90 istr := ""91 if m.Index != nil {92 istr = ", " + m.Index.W32()93 }94 scalestr := ""95 if m.Scale != nil {96 scalestr = ", " + m.Scale.Ptr()97 } else if m.Base == nil && m.Index == nil {98 scalestr = ", 1"99 }100 return offstr + "(" + bstr + istr + scalestr + ")"101}102func (m Memory) Add(off int) Memory {103 if m.Disp == nil {104 m.Disp = Imm32(off)105 return m106 }107 if d,ok := m.Disp.(Imm32); ok {108 m.Disp = d + Imm32(off)109 return m110 }111 if m.Scale == nil {112 if m.Index == nil {113 m.Index = Imm32(off)114 return m115 } else {116 switch i := m.Index.(type) {117 case Imm32:118 m.Index = i + Imm32(off)119 return m120 }121 }122 }123 panic(fmt.Sprintf("I don't know how to add to %s", m))124}125func (m Memory) Ptr() string {126 return m.W32()127}128// A Register refers to a general-purpose register, of which the x86129// has only eight, two of which are pretty much devoted to the stack.130type Register byte131const (132 EAX Register = iota133 EBX134 ECX135 EDX136 EDI137 ESI138 EBP139 ESP140)141func (r Register) String() string {142 switch r {143 case EAX: return "ax"144 case EBX: return "bx"145 case ECX: return "cx"146 case EDX: return "dx"147 case EDI: return "di"148 case ESI: return "si"149 case EBP: return "bp"150 case ESP: return "sp"151 }152 panic(fmt.Sprint("Bad register value: ", r))153}154func (r Register) W8() string {155 // I haven't come up with a great approach for handling the high156 // byte registers (with "h" at the end below). For now, I just157 // won't use them.158 switch r {159 case EAX: return "%al"160 case EBX: return "%bl"161 case ECX: return "%cl"162 case EDX: return "%dl"163 }164 panic(fmt.Sprint("Bad 8-bit register value: ", r))165}166func (r Register) W16() string {167 return "%" + r.String()168}169func (r Register) W32() string {170 return "%e" + r.String()171}172func (r Register) Ptr() string {173 return "%e" + r.String()174}175// Imm32 represents an immediate 32-bit value176type Imm32 int32177func (i Imm32) W32() string {178 return "$" + fmt.Sprint(i)179}180func (i Imm32) Ptr() string {181 return fmt.Sprint(i)182}183// Imm16 represents an immediate 16-bit value184type Imm16 int16185func (i Imm16) W16() string {186 return "$" + fmt.Sprint(i)187}188// Imm8 represents an immediate 8-bit byte189type Imm8 int8190func (i Imm8) W8() string {191 return "$" + fmt.Sprint(i)192}193// OpL2 holds any two-argument instructions involving 32-bit arguments194// of with the latter is an "output" argument. It shouldn't need to195// be exported, but it could also come in handy at some stage...196type OpL2 struct {197 name string198 src W32199 dest Ptr200}201func (o OpL2) X86() string {202 return "\t" + o.name + " " + o.src.W32() + ", " + o.dest.Ptr()203}204func MovL(src W32, dest Ptr) X86 {205 return OpL2{"movl", src, dest}206}207func AddL(src W32, dest Ptr) X86 {208 return OpL2{"addl", src, dest}209}210func AndL(src W32, dest Ptr) X86 {211 return OpL2{"andl", src, dest}212}213func ShiftLeftL(src W32, dest Ptr) X86 {214 return OpL2{"shll", src, dest}215}216func ShiftRightL(src W32, dest Ptr) X86 {217 return OpL2{"shrl", src, dest}218}219func IMulL(src W32, dest Ptr) X86 {220 return OpL2{"imull", src, dest}221}222// OpLL holds any two-argument instructions involving 32-bit arguments223// in which either could be immediate. It shouldn't need to be224// exported, but it could also come in handy at some stage...225type OpLL struct {226 name string227 src1, src2 W32228}229func (o OpLL) X86() string {230 return "\t" + o.name + " " + o.src1.W32() + ", " + o.src2.W32()231}232func CmpL(src W32, dest W32) X86 {233 return OpLL{"cmpl", src, dest}234}235// OpL1 holds any instruction involving a single 32-bit argument. It236// shouldn't need to be exported, but it could also come in handy at237// some stage...238type OpL1 struct {239 name string240 arg W32241}242func (o OpL1) X86() string {243 return "\t" + o.name + " " + o.arg.W32()244}245func Int(val W32) X86 {246 return OpL1{"int", val}247}248func PopL(dest W32) X86 {249 return OpL1{"popl", dest}250}251func PushL(src W32) X86 {252 return OpL1{"pushl", src}253}254type Op0 struct {255 name, comment string256}257func (o Op0) X86() string {258 return "\t" + o.name + "\t# " + o.comment259}260func Return(com string) X86 {261 return Op0{ "ret", com }262}263// OpL1 holds any instruction involving a single argument that must be264// an address. It shouldn't need to be exported, but it could also265// come in handy at some stage...266type OpP1 struct {267 name string268 arg Ptr269}270func (o OpP1) X86() string {271 return "\t" + o.name + " " + o.arg.Ptr()272}273func Jne(src Ptr) X86 {274 return OpP1{"jne", src}275}276func Call(src Ptr) X86 {277 return OpP1{"call", src}278}279func Jmp(src Ptr) X86 {280 return OpP1{"jmp", src}281}282// A Section is... a section.283type Section string284func (s Section) X86() string {285 return "." + string(s)286}287// Ascii is just raw text...288type Ascii string289func (a Ascii) X86() (out string) {290 // FIXME: This is stupidly O(N^2)...291 out = "\t.ascii\t\""292 for i := range a {293 switch a[i] {294 case '"': out += `\"`295 case '\n': out += `\n`296 default: out += string([]byte{a[i]})297 }298 }299 out += `"`300 return301}302// Int is just raw 32-bit number...303type GlobalInt int32304func (a GlobalInt) X86() string {305 return "\t.int\t" + fmt.Sprint(a)306}307// SymbolicConstant defines a symbolic constant...308type symbolicConstant struct {309 name Symbol310 value string311}312func (a symbolicConstant) X86() string {313 return "\t" + string(a.name) + " = " + a.value314}315func SymbolicConstant(name Symbol, val string) X86 {316 return symbolicConstant{name, val}317}318type RawAssembly string319func (r RawAssembly) X86() string {320 return string(r)321}322func GlobalSymbol(name string) X86 {323 return RawAssembly(".global " + name + "\n" + name + ":")324}...

Full Screen

Full Screen

debugging.go

Source:debugging.go Github

copy

Full Screen

1package x862var StartData = []X86{3 Section("data"),4 Symbol("goc.syscall"),5 Commented(GlobalInt(0),6 "This is a global variable for the address for syscalls"),7 Symbol("goc.args"),8 Commented(GlobalInt(0),9 "This is the number of args"),10 Symbol("goc.argsptr"),11 Commented(GlobalInt(0),12 "This is a pointer to the actual args"),13 Symbol("msg"),14 Commented(Ascii("Hello, world!\n"), "a non-null-terminated string"),15 Commented(SymbolicConstant(Symbol("len"), ". - msg"), "length of string"),16}17var StartText = []X86{18 Section("text"),19 Commented(GlobalSymbol("_start"), "this says where to start execution"),20 Call(Symbol("main_main")),21 Comment("And exit..."),22 Commented(MovL(Imm32(0), EBX), "first argument: exit code"),23 Commented(MovL(Imm32(1), EAX), "system call number (sys_exit)"),24 Int(Imm32(0x80)),25}26var Debugging = []X86{27 RawAssembly(`28# Debug utility routines!29print:30 movl 4(%esp), %edx # read the length31 movl 8(%esp), %ecx # pop the pointer to the string32 movl $2, %ebx # first argument: file handle (stderr)33 movl $4, %eax # system call number (sys_write)34 int $12835 popl %eax # store the return address36 addl $8, %esp # get rid of the two arguments37 jmp *%eax # return from println38println:39 movl 4(%esp), %edx # read the length40 movl 8(%esp), %ecx # pop the pointer to the string41 movl $2, %ebx # first argument: file handle (stderr)42 movl $4, %eax # system call number (sys_write)43 int $12844 # now we want to write a newline...45 movl $10, 4(%esp) # a newline46 movl $1, %edx # the length47 movl %esp, %ecx # the pointer48 addl $4, %ecx49 movl $2, %ebx # first argument: file handle (stderr)50 movl $4, %eax # system call number (sys_write)51 int $12852 popl %eax # store the return address53 addl $8, %esp # get rid of the two arguments54 jmp *%eax # return from println55debug.print_eax:56 pushl %edx # Save registers...57 pushl %ecx58 pushl %ebx59 pushl %eax60 movl %esp, %ecx # second argument: pointer to data61 addl $-20, %ecx # here I set up %ecx as my string pointer62 movl %eax, %ebx63 andl $15, %ebx64 shll $24, %ebx65 addl $805306368, %ebx # least significant hex66 movl %eax, %edx67 andl $240, %edx68 addl $768, %edx69 shll $12, %edx70 addl %edx, %ebx # second most significant hex71 movl %eax, %edx72 andl $3840, %edx73 addl $12288, %edx74 addl %edx, %ebx # third most significant hex75 movl %eax, %edx76 andl $61440, %edx77 addl $196608, %edx78 shrl $12, %edx79 addl %edx, %ebx # fourth most significant hex80 movl %ebx, 8(%ecx) # Store four bytes of hex notation, which covers 16 bits of EAX81 movl %eax, %edx82 andl $983040, %edx83 addl $3145728, %edx84 shrl $16, %edx85 movl %edx, %ebx # fifth most significant hex86 movl %eax, %edx87 andl $15728640, %edx88 addl $50331648, %edx89 shrl $12, %edx90 addl %edx, %ebx # sixth most significant hex91 movl %eax, %edx92 andl $251658240, %edx93 addl $805306368, %edx94 shrl $8, %edx95 addl %edx, %ebx # seventh most significant hex96 movl %eax, %edx97 shrl $4, %edx98 andl $251658240, %edx99 addl $805306368, %edx100 addl %edx, %ebx # eighth most significant hex101 movl %ebx, 4(%ecx) # Store four more bytes of hex notation, which covers the last 16 bits of EAX102 movl $10, 12(%ecx) # Add newline103 movl $980967781, (%ecx) # Add prefix104 movl $13, %edx # third argument: data length105 movl $1, %ebx # first argument: file handle (stdout)106 movl $4, %eax # system call number (sys_write)107 int $128108 popl %eax # Restore saved registers...109 popl %ebx110 popl %ecx111 popl %edx112 ret # from debug.print_eax113 `),114}...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful