Class: Ragweed::Rasm::Instruction
Overview
An X86 instruction. For the most part, you do two things with an instruction in Rasm: create it, and call to_s to get its raw value.
Direct Known Subclasses
Arith, Call, Cmp, IncDec, Int, Iret, Jcc, Jmp, Lea, Leave, Mov, Nop, Not, Pop, Popad, Popf, Push, Pushad, Pushf, Ret, Shift, Test
Instance Attribute Summary collapse
-
#dst ⇒ Object
Returns the value of attribute dst.
-
#src ⇒ Object
Returns the value of attribute src.
Class Method Summary collapse
Instance Method Summary collapse
-
#add(v, immed = false, half = false) ⇒ Object
Add material to the instruction.
- #coerce(v) ⇒ Object
- #dst_imm? ⇒ Boolean
- #dst_lab? ⇒ Boolean
- #dst_reg? ⇒ Boolean
-
#initialize(x = nil, y = nil) ⇒ Instruction
constructor
Never called directly (see subclasses below).
-
#locate(loc) ⇒ Object
What Subprogram#assemble uses to patch instruction locations.
-
#modrm(op1, op2) ⇒ Object
Calculate ModR/M bits for the instruction; this is the source/destination operand encoding.
-
#patch(patches) ⇒ Object
Not user-servicable.
- #sib(indir, alt, base) ⇒ Object
-
#src_imm? ⇒ Boolean
Are the source/dest operands immediates?.
-
#src_lab? ⇒ Boolean
Are the source/dest operands labels?.
-
#src_reg? ⇒ Boolean
Are the source/dest operands registers?.
-
#to_s ⇒ Object
Never called directly (see subclasses).
Constructor Details
#initialize(x = nil, y = nil) ⇒ Instruction
Never called directly (see subclasses below)
265 266 267 268 269 270 |
# File 'lib/ragweed/rasm/isa.rb', line 265 def initialize(x=nil, y=nil) @buf = Ragweed::Sbuf.new self.src = y self.dst = x @loc = nil end |
Instance Attribute Details
#dst ⇒ Object
Returns the value of attribute dst.
232 233 234 |
# File 'lib/ragweed/rasm/isa.rb', line 232 def dst @dst end |
#src ⇒ Object
Returns the value of attribute src.
231 232 233 |
# File 'lib/ragweed/rasm/isa.rb', line 231 def src @src end |
Class Method Details
.i(*args) ⇒ Object
234 |
# File 'lib/ragweed/rasm/isa.rb', line 234 def self.i(*args); self.new *args; end |
Instance Method Details
#add(v, immed = false, half = false) ⇒ Object
Add material to the instruction. Not user-servicable.
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/ragweed/rasm/isa.rb', line 358 def add(v, immed=false, half=false) return(nil) if not v if v.number? if (v < 0x100) and (v > -128) and not immed if v < 0 @buf.stl8(v.sx8) else @buf.stl8(v) end else if not half @buf.stl32(v.sx32) else @buf.stl16(v.sx16) end end else @buf.straw v end end |
#coerce(v) ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/ragweed/rasm/isa.rb', line 248 def coerce(v) if v v = v.derive v = v.to_i if v.kind_of? Ragweed::Ptr if v.kind_of? Array v = v[0].clone v.indir = true end v = Immed.new(v) if v.number? end v end |
#dst_imm? ⇒ Boolean
242 |
# File 'lib/ragweed/rasm/isa.rb', line 242 def dst_imm?; @dst and @dst.kind_of? Immed; end |
#dst_lab? ⇒ Boolean
246 |
# File 'lib/ragweed/rasm/isa.rb', line 246 def dst_lab?; @dst and @dst.kind_of? Label; end |
#dst_reg? ⇒ Boolean
238 |
# File 'lib/ragweed/rasm/isa.rb', line 238 def dst_reg?; @dst and @dst.kind_of? Register; end |
#locate(loc) ⇒ Object
What Subprogram#assemble uses to patch instruction locations. Not user-servicable
277 |
# File 'lib/ragweed/rasm/isa.rb', line 277 def locate(loc); @loc = loc; end |
#modrm(op1, op2) ⇒ Object
Calculate ModR/M bits for the instruction; this is the source/destination operand encoding.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/ragweed/rasm/isa.rb', line 293 def modrm(op1, op2) raise(BadArg, "two indirs") if op1.indir and op2.indir if op1.indir or op2.indir base = 0x80 (op1.indir) ? (o, alt = [op1,op2]) : (o,alt = [op2,op1]) if o.disp and (o.disp < 0x1000) base = 0x40 end if (not o.disp) or (o.disp == 0) base = 0x0 end end if op1.indir if op1.combined? or op1.scaled? or (op1.code == Register::EBP) sib(op1, op2, base) else return base + (op2.code << 3) + op1.code end elsif op2.indir if op2.combined? or op2.scaled? or (op2.code == Register::EBP) sib(op2, op1, base) else return base + (op1.code << 3) + op2.code end else return 0xc0 + (op2.code << 3) + op1.code end end |
#patch(patches) ⇒ Object
Not user-servicable
279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/ragweed/rasm/isa.rb', line 279 def patch(patches) if @dst.kind_of? Label raise(BadArg, "need to have location first") if not @loc offset = patches[@dst.val] - @Loc @dst = Immed.new offset if offset < 0 offset -= self.to_s @dst = Immed.new offset end end end |
#sib(indir, alt, base) ⇒ Object
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
# File 'lib/ragweed/rasm/isa.rb', line 324 def sib(indir, alt, base) modpart = (base+4) + (alt.code << 3) if indir.scaled? case indir.scale when 2 sbase = 0x40 when 4 sbase = 0x80 when 8 sbase = 0xc0 else raise BadArg, "scale must be 2, 4, or 8" end else sbase = 0 end col = indir.reg1.code if indir.combined? row = indir.reg2.code else row = 4 end # pp [col,row,sbase] sibpart = sbase + (row << 3) + (col) return (modpart.chr) + (sibpart.chr) end |
#src_imm? ⇒ Boolean
Are the source/dest operands immediates?
241 |
# File 'lib/ragweed/rasm/isa.rb', line 241 def src_imm?; @src and @src.kind_of? Immed; end |
#src_lab? ⇒ Boolean
Are the source/dest operands labels?
245 |
# File 'lib/ragweed/rasm/isa.rb', line 245 def src_lab?; @src and @src.kind_of? Label; end |
#src_reg? ⇒ Boolean
Are the source/dest operands registers?
237 |
# File 'lib/ragweed/rasm/isa.rb', line 237 def src_reg?; @src and @src.kind_of? Register; end |
#to_s ⇒ Object
Never called directly (see subclasses).
381 |
# File 'lib/ragweed/rasm/isa.rb', line 381 def to_s; ret = @buf.content; @buf.clear!; ret; end |