CSAPP与pushtest结果混淆练习问题4.7

时间:2019-07-11 08:01:59

标签: y86

Y86x86-64类似。为什么函数pushtest总是返回零?

正如我在x86-64上所知道的那样,推入操作首先要使ESP寄存器递减,而不要写。 首先读取Pop,然后再增加ESP寄存器。

    .text
.globl pushtest
pushtest:
    movq    %rsp, %rax
    pushq   %rsp
    popq    %rdx
    subq    %rdx, %rax
    ret

2 个答案:

答案 0 :(得分:0)

首先。您不应该手动修改%rsp(这是堆栈指针寄存器),不要执行movq %rsp, ...%rsppushpopcallret管理(并且必须由%rdx管理)。还要检查this question

那么最后总是movq %rsp, %rax ; %rsp==%rax pushq %rsp ; top of the stack := %rsp == %rax popq %rdx ; %rdx := top of the stack == %rax subq %rdx, %rax ; %rdx := %rdx - %rax , i.e. %rdx := %rax - %rax == 0 == 0,因为:

import * as mongoose from "mongoose";
import { pre, prop, Typegoose } from "./typegoose/src/typegoose";

@pre<Offer>("updateOne", function(this: mongoose.Query<any>) {
    // @ts-ignore
    this._update.isOfferLive = true;
    return;
})
class Offer extends Typegoose {
    @prop({ required: true, default: false })
    public isOfferLive: boolean;
}
const OfferModel = new Offer().getModelForClass(Offer);

(async () => {
    mongoose.set("debug", true);
    await mongoose.connect(`mongodb://mongodb:27017/`, {
        useNewUrlParser: true,
        useFindAndModify: true,
        useCreateIndex: true,
        dbName: "verify315",
        user: "user",
        pass: "passwd",
        authSource: "admin",
        autoIndex: true
    });

    const dummy = new OfferModel();
    await dummy.save();

    await dummy.updateOne(dummy).exec();

    const dummyback = await OfferModel.findById(dummy._id).exec(); // re-fetch because otherwise it does not load the changes
    console.log("after updateOne:", dummyback);

    await mongoose.disconnect();
})();

答案 1 :(得分:0)

我引用This answer,“ pushq”可以替换为“ subq and movq”,“ popq”可以替换为“ movq and addq”。

但是“ PUSH ESP”和“ POP ESP”是特例。参考This answer。 但是结果不是“ 0”

pushq%rsp ;将ESP寄存器的值推入执行指令之前的值。

popq%rsp ;在将旧堆栈顶部的数据写入目标之前,增加堆栈指针(ESP)。

pushq%rdx ;减小堆栈指针,然后将源操作数存储在堆栈顶部。

popq%rdx ;将值从堆栈顶部加载到目标操作数(或显式操作码)指定的位置,然后递增堆栈指针。

DECLARE @TempTable TABLE(
    DGTID INT,
    SKAcc VARCHAR(MAX),
    Linkedaccount VARCHAR(MAX),
    DGTStatus VARCHAR(1)
)

INSERT INTO @TempTable (DGTID,SKAcc,Linkedaccount,DGTStatus)
VALUES( 1,'8002180831','8102651144,8005370302','C' ),
( 2,'8005370302','8002170111','I'),
( 3,'8002012348',NULL,'I' )

SELECT * FROM @TempTable

UPDATE A
SET A.DGTStatus = 'C'
FROM @TempTable A
INNER JOIN @TempTable B ON B.Linkedaccount LIKE '%'+CAST(A.SKAcc AS VARCHAR(MAX))+'%'
AND  B.DGTStatus = 'C'

SELECT * FROM @TempTable